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

Get fractional part of a number using IEEE754

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

    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 -> 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字节

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

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

没有任何黑客可以提取最初不存在的数据。