【发布时间】:2012-06-05 12:09:21
【问题描述】:
比较一些 C 代码和我试图替换它的 F#,我观察到最终结果存在一些差异。
在备份代码时,我发现即使存在差异 - 尽管很小。
代码首先从文件中读取数据。第一个数字的结果不同。例如,在 F# 中(更易于编写脚本):
let a = 71.9497985840
printfn "%.20f" a
我得到了预期的(对我而言)输出71.94979858400000000000。
但在 C 中:
a = 71.9497985840;
fprintf (stderr, "%.20f\n", a);
打印出71.94979858400000700000。
那个 7 是从哪里来的?
差异很小,但它困扰着我,因为我不知道为什么。 (这也让我很困扰,因为它让我更难追踪我的两个版本代码的分歧)
【问题讨论】:
-
你确定两个值都是双倍的吗?您确定错误不在打印中吗?
-
.net 中的浮点运算没有明确定义的精确结果。这只是一个近似值。编译器和 JITer 会随心所欲地更改低位数字,只需用
printfn之类的东西观察它们就会影响它们。 -
使用调试器或其他工具查看变量的确切位模式。如果您拥有的 F# 和 C 实现都使用相同的浮点格式并且变量具有完全相同的位模式,那么区别在于打印或编译器如何解析浮点文字。在任何一种情况下,由于浮点数只是近似值,因此可能没有什么可担心的,因为差异非常小。
-
我看到至少三种不同的可能性:1)ToString 转换不同 2)编译器中的 String 到 Double 转换不同 3).net 代码使用了更高的精度数(通常很常见,但非常在这种特定情况下不太可能)
-
您在 F# 中看到的值不是确切的值。在此处尝试 DoubleConverter 类以查看确切值:stackoverflow.com/a/3495263/93652
标签: .net c floating-point