我如何证明 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
更好地理解 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)
和
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<sup>-1</sup>
或 0.5
.[=40= 的乘数]
尾数位是 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, 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>
因为 n
从 1
开始并向右增加:
<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)
我用第二个问题稍微修改了原始消息:
一位 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)
和
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<sup>-1</sup>
或 0.5
.[=40= 的乘数]
尾数位是 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, 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>
因为 n
从 1
开始并向右增加:
<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)