简体   繁体   English

gcc 和 Ubuntu 上的舍入不正确

[英]Incorrect rounding on gcc and Ubuntu

I am currently porting some codes from Windows to Linux (Ubuntu) from a MS VS2008 compiler to GCC.我目前正在将一些代码从 Windows 移植到 Linux (Ubuntu),从 MS VS2008 编译器移植到 GCC。

The problem is that the following code has different results:问题是以下代码有不同的结果:

double            d = 19.53125;
std::cout.precision(4);
std::cout.setf(std::ios::fixed);

std::cout << d << std::endl;

Windows output: 19.5313
Linux output: 19.5312

If I set the precision to 5 the output is the same.如果我将精度设置为 5,则 output 是相同的。

I expect that 19.53125 will be rounded up to 19.5313.我预计 19.53125 将四舍五入为 19.5313。

Any suggestions how I can get the desired rounding behavior?有什么建议可以让我获得所需的舍入行为吗?

Note: Windows code runs native on Windows 10 laptop and the Linux code runs inside a 64-bit Ubuntu 18.04 LTS VM.注意:Windows 代码在 Windows 10 笔记本电脑上本地运行,而 Linux 代码在 64 位 Ubuntu 18.04 LTS VM 中运行。

Bankers Rounding is an algorithm for rounding quantities to integers, in which numbers which are equidistant from the two nearest integers are rounded to the nearest even integer. Thus, 0.5 rounds down to 0; Bankers Rounding 是一种将数量四舍五入为整数的算法,其中与最接近的两个整数等距的数字四舍五入到最接近的偶数 integer。因此,0.5 向下舍入为 0; 1.5 rounds up to 2. 1.5 四舍五入到 2。

GCC C++ standard library applies the Bankers Rounding. GCC C++ 标准库应用 Bankers Rounding。 19.53125 -> 19.5312, since 2 is the nearest even digit. 19.53125 -> 19.5312,因为 2 是最接近的偶数。

Additional info regarding C, but C++ respects C rounding: C++ Rounding behavior consistency for ties with sprintf有关 C 的附加信息,但 C++ 尊重 C 舍入: C++ 与 sprintf 关系的舍入行为一致性

This has been an eye opener for me.这让我大开眼界。 Thanks for all the links.感谢所有链接。 As I have not been able to find a way to influence the rounding behavior in the printf functions I don't see another solution then to use the math round function.由于我无法找到一种方法来影响 printf 函数中的舍入行为,因此我看不到另一个解决方案,然后使用数学舍入 function。

The below solution still works for me:以下解决方案对我仍然有效:

double         d = 19.53125;
int precision  p = 4;
double         factor = pow(10.0, p);
std::cout.precision(p);
std::cout.setf(std::ios::fixed);

std::cout << round(d * factor) / factor << std::endl;

Windows output: 19.5313
Linux output: 19.5313

Links:链接:

  1. https://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/ https://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/
  2. Why printf round floating point numbers? 为什么printf是整数浮点数?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM