在sprintf中舍入Windows与基于Unix的系统的差异

gro*_*rtn 10 c c++ unix windows rounding-error

我在基于UNIX的系统上遇到问题sprintf没有正确地舍入值.

例如

double tmp = 88888888888885.875
char out[512];
Run Code Online (Sandbox Code Playgroud)

这是88,888,888,888,885.875只是为了让眼睛更容易.我给出了这样一个特别而又大的例子,因为它似乎在较小的数字上工作正常.

我试图以下面的方式使用它

sprintf(out, "%021.2f", tmp);
printf("out = %s\n", tmp);
Run Code Online (Sandbox Code Playgroud)

在Windows上,这会导致:

out = 000088888888888885.88
Run Code Online (Sandbox Code Playgroud)

例如AIX,但在Linux中也显示:

out = 000088888888888885.87
Run Code Online (Sandbox Code Playgroud)

为什么会这样?任何想法以及如何使它在Win/Unix上的行为方式相同

谢谢

ssm*_*mir 1

有一个glibc 的错误报告,其问题与您的问题非常相似。这里的主要结论(在评论 46 中)是 double 不是一个 15 位十进制数字,你不应该期望它像那样工作。

作为解决方法,您可以在数字中添加一些小内容以使它们更好地舍入。但这个解决方案并不通用,因为它取决于您处理的数字范围。

另一种解决方法可以是乘以准备舍入,然后舍入(例如2597.625*100 = 259762.5 -> 259763 = 2597.63*100

但我认为必须有更明智的解决方法。