| [ CnUnix ] in KIDS 글 쓴 이(By): doldori (돌돌이) 날 짜 (Date): 2003년 8월 18일 월요일 오후 11시 18분 35초 제 목(Title): Re: [Q] data 저장 방법... 재미있는 문제네요. 한가한 틈을 타서 코딩을 해봤습니다. 10 bits : mantissa 1 bit : sign 5 bits : exponent 로 담으려면 bit operation이 필요할 것 같고 char[2] 형으로 데이터를 저장하기 때문에 byte ordering 문제는 없을 것으로 생각합니다. portability나 efficiency에 대해서는 자신 없습니다. -.- #include <iostream> #include <fstream> #include <limits> #include <cmath> #include <cstdlib> int encode(double d, unsigned char code[]) { double absd = fabs(d); if (absd >= 1.e16 || absd < 1.e-16) return 1; code[0] = code[1] = 0; unsigned char sign = (d >= 0) ? 0 : 1; unsigned char exp = 18; // 지수 범위 -16 ~ 15는 0 ~ 31로 처리 if (absd < 100) { while (absd < 100) { absd *= 10; --exp; } } else if (absd >= 1000) { while (absd >= 1000) { absd /= 10; ++exp; } } unsigned mantissa = unsigned(absd + 0.5); // 반올림 code[0] = mantissa >> 2; code[1] = mantissa << (CHAR_BIT - 2); code[1] |= sign << (CHAR_BIT - 3); code[1] |= exp; return 0; } double decode(const unsigned char code[]) { unsigned char sign = (code[1] & 0x20) ? 1 : 0; unsigned char exp = code[1] & 0x1f; unsigned mantissa = code[0] << 2; mantissa |= code[1] >> (CHAR_BIT - 2); double d = mantissa; if (exp > 18) while (exp-- > 18) d *= 10; else if (exp < 16) while (exp++ < 18) d /= 10; if (sign) d *= -1; return d; } int main() { using namespace std; ofstream fout("data", ios_base::out | ios_base::binary); if (!fout.is_open()) exit(1); unsigned char code[2]; double d; while (cin >> d) { if (!encode(d, code)) fout.write((char*)code, 2); } fout.close(); ifstream fin("data", ios_base::in | ios_base::binary); if (!fin.is_open()) exit(2); while (fin.read((char*)code, 2)) { d = decode(code); cout << d << endl; } fin.close(); } |