我正在替换一些用C++(NET6)编写二进制文件的C++代码,我注意到写入文件的值之间的差异.

如果我的双精度值等于0,C++将字节写入:

00 00 00 00 00 00 00 00

但是C#(使用BinaryWriter)写入的值与:

00 00 00 00 00 00 00 80

如果我使用系统将0.0转换为字节.比特转换器.GetBytes(),我得到所有0x00.如果我使用位转换器将带有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是sign bit.这意味着存储的数字实际上是-0.0(在几乎所有情况下,它都等于0.0,所以应该不会造成任何问题).

事实上,there are other bits(exponent中)可以设置为1,但仍将表示的double的值保留为(+/-)零.

我们是怎么拿到-0.0块的?在没有看到生成值的代码的情况下不能说,但是,来自同一个Wiki页面:

某些计算的结果可能是负零,

.net相关问答推荐

如何在AutoMapper中添加自定义方法到项目中?

如何从 tshark 的 stderr 捕获实时数据包计数?

Azure SignalR 和微服务

.NET MAUI 的登录页面

图像 UriSource 和数据绑定

为什么这两个比较有不同的结果?

.NET 应用程序的链接器状态(又名请先生,我可以有一个链接器2009 年版)

IIS Express - 500.19 无法读取配置文件 - 因为它正在查看错误的路径

为什么 ?: 会导致转换错误,而 if-else 不会?

如何在 C# 中直接执行 SQL 查询?

如何将 NuGet 与 Visual C# Express 一起使用?

您可以在 C# 代码中捕获本机异常吗?

双倍的? = 双倍? + 双倍?

Visual Studio 2017 和 2019 突出显示滚动条中所选单词的出现

如何获得 Bin 路径?

将月份 int 转换为月份名称

WebClient.DownloadString 由于编码问题导致字符损坏,但浏览器正常

SqlCommand.CommandTimeout 和 SqlConnection.ConnectionTimeout 有什么区别?

WinForms 中的模型视图演示者

在类型 c# 上切换大小写