我已经由C ++专家建议解决这一问题:https://en.cppreference.com/w/cpp/numeric/bit_cast
以更好地理解double
,memcpy
和bit_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)
with
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.1110
(3fe
),它是1022
,但通过1023
向下调节以处理负指数。因此,它是-1
,为您提供了2-1
或0.5
的乘数。
尾数位是1001000..0
(您的十六进制数字的9000..0
)。前四个位等于值0.5
,0.25
,0 .0125
和0.0625
(每次减半)。由于仅设置了第一位和第四位,因此得到0.5 + 0.0625 = 0.5625
。
根据IEEE754的要求,将隐式1
添加到该数字中,您将得到一个基本值1.5625
。将其乘以先前计算的乘数后,您将得到:
1.5625 x 0.5 = 0.78125
所以那是>>您如何获得价值。
可以在IEEE754-1985 Wikipedia page上找到更多详细信息,您可以尝试使用Harald Schmidt's excellent online converter这个非常有用的工具,我也建立了自己的副本来处理双精度(不幸的是,不是在网上,桌面版Java应用)。确实did
有助于我的理解。