CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ 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();
}
[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.