使用IEEE754获取数字的小数部分

时间:2015-01-22 21:58:30

标签: c# .net floating-point ieee-754

我有一个使用循环工作的代码但是它很糟糕,因为可以简化。我的意思是这个循环:

    private static long GetFract(double d)
    {
        if (d < 0)
            return GetFract(-d);
        d -= Math.Truncate(d);
        long result = 0;
        checked
        {
            while (true)
            {
                try
                {
                    d *= 10;
                    long tmp = (long)d;
                    if (Math.Abs(tmp - d) < double.Epsilon)
                        return tmp;
                    result = tmp;
                }
                catch
                {
                    return result;
                }
            }
        }
    }

预期结果:2.3333 - &gt; 3333

那么我们可以使用IEEE754来获取数字的小数部分而不使用ToString()Split()和其他函数,只使用FP和整数数学?我的意思是有点神奇:

    private static unsafe long GetFract(double d)
    {
        if (d < 0)
            return GetFract(-d);
        d -= Math.Truncate(d);
        const long mask = 0xFFFFFFFFFFFFF; //some magic const here
        long x = *((long*) &d);
        return x & mask;
    }

我们假设d总是在[0..1]中,long和double都是8个字节

1 个答案:

答案 0 :(得分:3)

3333的IEEE 754表示中找不到表示数字2.3333的位序列,也没有0.3333,因为IEEE 754使用二进制指数,而不是十进制。

也就是说,你正在寻找3333 / 10000中的分子,但内部表示是(当转换为十进制时)6004199023210345 / 18014398509481984(分母为2 54

没有任何一点可以提取首先不存在的数据。