为什么C和c#的双精度不同?

本文关键字:双精度 为什么 | 更新日期: 2023-09-27 18:08:25

我正在尝试将旧系统的一部分重写为c#程序。旧的程序都是用c语言编写的。这两个程序都将blob文件读入字节数组,并用数据填充对象/结构体。

在原始的C代码中,这是通过read()

完成的
fread(&myStruct, sizeof(MYSTRUCT), 1, data)
fseek(data, 256, 0)
fread(&nextStruct, sizeof(NEXTSTRUCT), 1, data)

在c#中使用二进制读取器

using(BinaryReader reader = new BinaryReader(stream)){
  double1 = reader.ReadDouble();
  double2 = reader.ReadDouble();
  reader.BaseStream.Position = 256;
  short1 = reader.ReadInt16();
   ... and so on ...
}

在大多数情况下,运行程序的结果是相同的,但有时会有小的偏差,有些blobs会有巨大的偏差。

在调试具有洞察力的C代码时,我看到从blob提取后的值是不一样的。


例子在c#中,我得到212256608402。688在C 212256608402。68799
在c#中,我得到了2.337在C中,2.3370000000000001为短值

这个差异的原因是什么,它是可以修复的吗?
在某些方法汇总所有条目(最多一百万)并计算一些值之后,这会导致5%或更多的错误吗?还有其他可能导致错误结果的陷阱需要注意吗?

为什么C和c#的双精度不同?

2.3370000000000001 == 2.337212256608402.688 == 212256608402.68799。这些字符串在解析时产生逐位相同的double s。double没有足够的精度来区分这些实数,它们都四舍五入到相同的值。精度没有差别,只是打印的数字数量不同。