C++ 和 C# 双精度十六进制值之间的差异

Wal*_*ams 8 .net c# c++ byte

我正在用 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
Run Code Online (Sandbox Code Playgroud)

这似乎不会造成任何问题,但我想了解发生了什么。

Adr*_*ica 7

正如评论中提到的,该尾随0x80字节实际上是该值的字节double。因此,设置的 MSB 就是符号位。这意味着存储的数字实际上是-0.0(在几乎所有情况下,比较等于0.0,因此它不会导致任何问题)。

\n

事实上,还有其他位(在指数中)可以设置为 1,但仍将表示的值保留double为 (+/-) 零。

\n

我们是怎么得到的-0.0?如果没有看到生成该值的代码,就不能说,但是,来自同一个 Wiki 页面:

\n
\n

作为某些计算的结果,\n可能会得到负零,\n例如,作为负数的算术下溢的结果\n(也可能有其他结果),或 \xe2\x88\x921.0\xc3\x970.0 ,或简称为\n\xe2\x88\x920.0。

\n
\n