C双打是否与.NET双打不同?

Ben*_*jol 10 .net c floating-point

比较一些C代码和F#我试图替换它,我观察到最终结果存在一些差异.

重新编写代码,我发现即使存在差异 - 尽管很小.

代码首先从文件中读取数据.而第一个数字则不同.例如,在F#中(更容易编写脚本):

let a = 71.9497985840
printfn "%.20f" a
Run Code Online (Sandbox Code Playgroud)

我得到了预期的(对我而言)输出71.94979858400000000000.

但在C:

a =  71.9497985840;
fprintf (stderr, "%.20f\n", a);
Run Code Online (Sandbox Code Playgroud)

打印出来71.94979858400000700000.

那7来自哪里?

差别很小,但它困扰我,因为我不知道为什么.(它也困扰我,因为它更难以追踪我的两个版本的代码分歧的位置)

Dan*_*her 7

这是印刷的差异.将该值转换为IEEE754会double产生

Prelude Text.FShow.RealFloat> FD 71.9497985840
71.94979858400000694018672220408916473388671875
Run Code Online (Sandbox Code Playgroud)

但该表示71.949798584足以将数字与其邻居区分开来.C,当要求在小数点后以20位数的精度打印时,将正确舍入的值转换为所需的位数,显然F#使用最短的唯一确定表示并用所需数量的0填充它,就像Haskell一样.

  • @Benjol:澄清Daniel Fischer所说的内容:只要.NET和C运行时都遵循IEEE-754标准(也称为ISO/IEC 60559),那么计算的实际值将是相同的.您在此处观察到的差异是运行时*以不同方式打印*值,而不是表示的值存在实际差异.因此,任何数量的附加操作都不会导致此错误累积,因为"错误"(或更严格地说,差异)仅在结果转换为十进制时才出现以用于显示目的. (2认同)