比较一些C代码和F#我试图替换它,我观察到最终结果存在一些差异。
重新编写代码,我发现即使存在差异 - 尽管很小。
代码首先从文件中读取数据。而第一个数字则不同。例如,在F#中(更容易编写脚本):
let a = 71.9497985840
printfn "%.20f" a
我得到了预期的(对我而言)输出71.94979858400000000000
。
但在C:
a = 71.9497985840;
fprintf (stderr, "%.20f\n", a);
打印出71.94979858400000700000
。
那7来自哪里?
差别很小,但令我困扰,因为我不知道为什么。 (这也困扰我,因为它更难以追踪我的两个版本的代码分歧的位置)
答案 0 :(得分:7)
这是印刷中的差异。将该值转换为IEEE754 double
会产生
Prelude Text.FShow.RealFloat> FD 71.9497985840
71.94979858400000694018672220408916473388671875
但是表示71.949798584
足以将数字与其邻居区分开来。 C,当要求在小数点后以20位数的精度打印时将正确舍入的值转换为所需的位数,显然F#使用最短的唯一确定表示并用所需数量的0填充它,就像Haskell一样
答案 1 :(得分:3)
这只是不同的四舍五入。数字是相同的(根据CPython,至少):
>>> '%.44f' % 71.94979858400000000000
'71.94979858400000694018672220408916473388671875'
>>> '%.44f' % 71.94979858400000700000
'71.94979858400000694018672220408916473388671875'
答案 2 :(得分:3)
这是.NET System.Double.ToString()方法的不同之处,即将double转换为字符串的方法。您可以通过下载SSCLI20中提供的CLR源来查看相关代码。转换由clr / src / vm / comnumber.cpp,COMNumber :: FormatDouble()函数完成。看起来like this,代码中的注释最能描述正在发生的事情:
//In order to give numbers that are both friendly to display and round-trippable,
//we parse the number using 15 digits and then determine if it round trips to the same
//value. If it does, we convert that NUMBER to a string, otherwise we reparse using 17 digits
//and display that.
C运行时库没有该功能。
答案 3 :(得分:0)
其他答案充分解释了问题的根源(双精度和舍入)。
如果您的数字通常是中等数量且小数精度非常重要(比计算速度更快),那么可以考虑使用.NET decimal
格式。这为您提供了28-29个精确的小数位精度,而没有像double那样的小数二进制舍入误差。限制是范围较小(没有大的指数!)。
http://msdn.microsoft.com/en-us/library/364x0z75%28v=vs.100%29.aspx
答案 4 :(得分:0)
对于任何绊脚石的人的进一步信息。
使用找到here的代码,我已经确认(我相信)基础二进制表示(至少对于这个特定数字)是相同的断言。
以下是代码示例 - 请注意'将零乘以零'以消除负零 - 这在转换为long时很难看。
//(C# this time)
var d = 71.9497985840; //or other incoming double value
if(d == 0) d = d * d; //for negative zero
var longval = System.BitConverter.DoubleToInt64Bits(d); // = 4634763433907061836
在C:
double d;
long long a;
d = 71.9497985840; //or other incoming double value
if(d == 0) d = d * d; //for negative zero
a = *(long long*)&d; //= 4634763433907061836
更新 - 我接着,发现在矩阵求逆期间引入了差异,因为每个系统都调用了不同的库,以不同的方式实现反转...