python - 在 Windows 上模拟 Linux 的浮点字符串转换行为

标签 python c floating-point printf precision

我在输出 float 时遇到了一个烦人的问题。当我在 Windows 上以 2 个小数点的精度格式化 11.545 时,它输出“11.55”,正如我所期望的那样。但是,当我在 Linux 上执行相同操作时,输出为“11.54”!

我最初是在 Python 中遇到这个问题,但进一步调查表明差异在于底层 C 运行时库。 (两种情况下的体系结构都是 x86-x64。)运行以下 C 行在 Windows 和 Linux 上会产生不同的结果,这与在 Python 中的结果相同。

printf("%.2f", 11.545);

为了更清楚地说明这一点,我将数字打印到小数点后 20 位 ("%.20f"):

Windows: 11.54500000000000000000
Linux:   11.54499999999999992895

我知道 11.545 不能精确存储为二进制数。因此,似乎正在发生的事情是 Linux 以尽可能高的精度输出它实际存储的数字,而 Windows 输出它的最简单的十进制表示形式,即。尝试猜测用户最有可能的意思。

我的问题是:是否有任何(合理的)方法来模拟 Windows 上的 Linux 行为?

(虽然 Windows 行为当然是直观行为,但在我的例子中,我实际上需要将 Windows 程序的输出与 Linux 程序的输出进行比较,而 Windows 是我唯一可以更改的。顺便说一下,我试图查看 printf 的 Windows 源代码,但执行 float->string 转换的实际函数是 _cfltcvt_l 并且它的源代码似乎不可用。 )

编辑:情节变厚了!关于这是由不精确表示引起的理论可能是错误的,因为 0.125 确实有一个精确的二进制表示,并且当使用 '%.2f' % 0.125 输出时它仍然不同:

Windows: 0.13
Linux:   0.12

但是,round(0.125, 2) 在 Windows 和 Linux 上都返回 0.13。

最佳答案

首先,在这种情况下,听起来 Windows 的错误是正确的(但这并不重要)。 C 标准要求 %.2f 输出的值四舍五入到适当的位数。最著名的算法是 dtoaDavid M. Gay 实现.您或许可以将其移植到 Windows 或找到 native 实现。

如果您还没有读过 Steele 和 White 的“如何准确打印 float ”,请找一本读一读。这绝对是一本启发性的读物。一定要找到 70 年代后期的原作。我认为我在某个时候从 ACM 或 IEEE 购买了我的。

关于python - 在 Windows 上模拟 Linux 的浮点字符串转换行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2234303/

相关文章:

c++ - 在 C 和 C++ 中, "#"是什么意思?

java - 算术比较以避免浮点错误

c++ - 为什么不将有理数实现并存储为零丢失信息的分数?

python - 考虑删除获取接近的字符串匹配 - python

Python - 使用操作系统重命名文件两次

python - 使文本看起来像是在 Python Shell 中输入的

bash - Bash 中具有浮点值的 C 风格算术

python - keras 理解词嵌入层

sql - DeepMind如何减少Atari游戏Q值的计算?

c - 在这种情况下,从用户在 C 中输入的字符串中提取子字符串的最佳方法是什么