我如何证明 f64::from_bits(0x3fe9000000000000 u64 ) == 0.781250 f64

How can I justify that f64::from_bits(0x3fe9000000000000 u64 ) == 0.781250 f64

我用第二个问题稍微修改了原始消息:

一位 C++ 专家建议我检查一下: https://en.cppreference.com/w/cpp/numeric/bit_cast

更好地理解 doublememcpybit_cast (C++20) 的表示。

在这里更具体地说,我试图理解为什么我们从代码中得到这样的结果:

    constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
    constexpr auto f64v2 = std::bit_cast<double>(u64v2);

"f64::from_bits(0x3fe9000000000000u64) == 0.781250f64"

在此之前,我花时间研究了快速平方根反比示例中提供的示例。

https://en.wikipedia.org/wiki/Fast_inverse_square_root#CITEREFGoldberg1991

我手动做了微积分,结果我终于意识到在这个特定情况下会发生什么,指数为 8 位,尾数为 23 位。

但是在我上面提到的作为bit_cast的应用的例子中,根据我的研究似乎指数是11位,尾数是52位(双精度): https://en.wikipedia.org/wiki/Double-precision_floating-point_format

当我手工计算时,我发现

x = (1+Mx/L)*2^(Ex-B)

 L=2^52 and Ex = 2*(2^9- 1) with the notations of 

https://en.wikipedia.org/wiki/Fast_inverse_square_root#CITEREFGoldberg1991

而且我没有找到公布的 `0.781250 结果。 也许我选择的指数和尾数不正确。 我不知道,但我真的很想了解发生了什么。

提前感谢您的解释帮助找到 0.781250

第二个问题:请你检查一下我在下面提出的问题作为对评论的回复,因为即使我对第一个例子也有疑问。提前致谢

对于3fe9000000000000,第一位(零)是符号位,所以我们可以忽略它(它是正数)。

接下来的 11 位是 011.1111.11103fe),也就是 1022,但向下调整了 1023 以处理负指数。因此,它是 -1,它为您提供 2<sup>-1</sup>0.5.[=40= 的乘数]

尾数位是 1001000..0(您的十六进制数的 9000..0)。前四位等于值 0.50.250.01250.0625(每次减半)。由于仅设置了第一位和第四位,因此您得到 0.5 + 0.0625 = 0.5625.

根据 IEEE754 的规定,将隐式 1 添加到该数字,您将获得 1.5625 的基值。当它乘以之前计算的乘数时,您将得到:

1.5625 x 0.5 = 0.78125

所以这就是你如何获得你的价值。


可以在 IEEE754-1985 Wikipedia page, and you can experiment with Harald Schmidt's excellent online converter 上找到更多详细信息,这是一个非常有用的工具,我构建了自己的副本来处理双精度(不幸的是,它不是在网络上,它是一个 Java 桌面应用程序)。它确实确实对我的理解帮助很大。

您可能还想特别查看 some other answers I've given on IEEE754, including, this one


关于您在评论中提出的位模式,0x4172f58bc0000000(您声明 应该 19880124 但计算其他内容),这是你如何转换它:

4---> 1--> 7-->   2--> f--> 5--> 8--> b--> c--> (<- hex digits)
s eee eeee eeee   mmmm mmmm mmmm mmmm mmmm mmmm
0 100 0001 0111   0010 1111 0101 1000 1011 1100 (<- then all zeroes)
  v      v  vvv     |  ||||  | | |    | || ||            1/n
  1      1  421     |  ||||  | | |    | || |+-------- 4,194,304
  0      6          |  ||||  | | |    | || +--------- 2,097,152
  2                 |  ||||  | | |    | |+----------- 1,048,576
  4                 |  ||||  | | |    | +------------   524,288
                    |  ||||  | | |    +--------------   131,072
                    |  ||||  | | +-------------------     8,192
                    |  ||||  | +---------------------     4,096
                    |  ||||  +-----------------------     1,024
                    |  |||+--------------------------       256
                    |  ||+---------------------------       128
                    |  |+----------------------------        64
                    |  +-----------------------------        32
                    +--------------------------------         8

符号为正。

指数为1,024 + 16 + 4 + 2 + 1 = 1,047 - 1,023 bias = 24,所以乘数为2<sup>24</sup>16,777,216.

尾数位求和,每一位相加<sup>1</sup>/<sub>2<sup>n</sup></sub> 因为 n1 开始并向右增加:

<sup>1</sup>/<sub>4,194,304</sub>, <sup>1</sup>/<sub>2,078,152</sub>, <sup>1</sup>/<sub>1,048,576</sub>, <sup>1</sup>/<sub>524,288</sub>, <sup>1</sup>/<sub>131,072</sub>, <sup>1</sup>/<sub>8,192</sub>, <sup>1</sup>/<sub>4,096</sub>, <sup>1</sup>/<sub>256</sub>, <sup>1</sup>/<sub>128</sub>, <sup>1</sup>/<sub>64</sub>, <sup>1</sup>/<sub>32</sub>, 和 <sup>1</sup>/<sub>8</sub>.

当您将所有这些与隐含的 1 相加时,您会得到 1.1849477291107177734375.

那么,那个和前面计算的乘数16,777,216的乘积就是你想要的值,19,880,124‬

以下是您的号码在 IEEE-745 DP 格式中的布局方式:

                  6    5          4         3         2         1         0
                  3 21098765432 1098765432109876543210987654321098765432109876543210
                  S ----E11---- ------------------------F52-------------------------
          Binary: 0 01111111110 1001000000000000000000000000000000000000000000000000
             Hex: 3FE9 0000 0000 0000
       Precision: DP
            Sign: Positive
        Exponent: -1 (Stored: 1022, Bias: 1023)
       Hex-float: +0x1.9p-1
           Value: +0.78125 (NORMAL)