我正在替换一些用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相关问答推荐

Long.MaxValue从Single到Long的转换导致溢出异常

如何查询 DOTNET_CLI_TELEMETRY_OPTOUT 是否永久设置为 TRUE?

Ubuntu 22.04 + JetBrains Rider 不能做脚手架 dbContext

为什么我在环境变量中有不同的值?

通过 System.Net.Mail 的 VB SMTP 停止工作

将字符串与容差进行比较

process.WaitForExit() 异步

使用字典作为数据源绑定组合框

编译时禁用 Dll 文化文件夹

哪个单元测试框架?

找不到 Assert.Fail 和 Assert.Pass 或等效项

在 C# 中与块等效?

如何使用配置转换删除 ConnectionString

如何禁用 Alt + F4 关闭表单?

文件按文件名模式存在

如何在 C# 中以编程方式安装 Windows 服务?

如何从 .NET 读取 PEM RSA 私钥

在 WPF DataGrid 中绑定 ComboBoxColumn 的 ItemsSource

在不使用while循环的情况下找到最里面的异常?

嵌套捕获组如何在正则表达式中编号?