双打的 C++ 和 C# 十六进制值之间的区别
Difference between C++ and C# hex values for doubles
我正在用 C# (net6.0) 替换一些写入二进制文件的 C++ 代码,我注意到写入文件的值之间存在差异。
如果我有一个等于 0.0 的双精度值,C++ 将字节写为:
00 00 00 00 00 00 00 00
但是 C#(使用 BinaryWriter)正在写入与以下相同的值:
00 00 00 00 00 00 00 80
如果我使用 System.BitConverter.GetBytes() 将 0.0 转换为字节,我得到所有 0x00。如果我使用 BitConverter 将 0x80 的字节转换为双字节,它仍然给我 0.0.
byte[] zero = System.BitConverter.GetBytes(0.0); // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
bool equal = 0.0 == System.BitConverter.ToDouble(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}); // true
这似乎不会引起任何问题,但我想了解发生了什么。
如评论中所述,尾随 0x80
字节实际上是 double
值的 high 字节。因此,其中设置的 MSB 是 符号位 。这意味着存储的数字实际上是 -0.0
(在几乎所有情况下,它都等于 0.0
,因此它不会造成任何问题)。
事实上,there are other bits(在指数中)可以下注设置为1但仍然保留表示的double
的值作为(+ /-) 零。
我们是怎么得到-0.0
的?不能说没有看到生成值的代码,但是来自同一个 Wiki 页面:
One may obtain negative zero as the result of certain computations,
for instance as the result of arithmetic underflow on a negative
number (other results may also be possible), or −1.0×0.0, or simply as
−0.0.
我正在用 C# (net6.0) 替换一些写入二进制文件的 C++ 代码,我注意到写入文件的值之间存在差异。
如果我有一个等于 0.0 的双精度值,C++ 将字节写为:
00 00 00 00 00 00 00 00
但是 C#(使用 BinaryWriter)正在写入与以下相同的值:
00 00 00 00 00 00 00 80
如果我使用 System.BitConverter.GetBytes() 将 0.0 转换为字节,我得到所有 0x00。如果我使用 BitConverter 将 0x80 的字节转换为双字节,它仍然给我 0.0.
byte[] zero = System.BitConverter.GetBytes(0.0); // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
bool equal = 0.0 == System.BitConverter.ToDouble(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}); // true
这似乎不会引起任何问题,但我想了解发生了什么。
如评论中所述,尾随 0x80
字节实际上是 double
值的 high 字节。因此,其中设置的 MSB 是 符号位 。这意味着存储的数字实际上是 -0.0
(在几乎所有情况下,它都等于 0.0
,因此它不会造成任何问题)。
事实上,there are other bits(在指数中)可以下注设置为1但仍然保留表示的double
的值作为(+ /-) 零。
我们是怎么得到-0.0
的?不能说没有看到生成值的代码,但是来自同一个 Wiki 页面:
One may obtain negative zero as the result of certain computations, for instance as the result of arithmetic underflow on a negative number (other results may also be possible), or −1.0×0.0, or simply as −0.0.