uncletall
uncletall

Reputation: 6842

Incorrect rounding on gcc and Ubuntu

I am currently porting some codes from Windows to Linux (Ubuntu) from a MS VS2008 compiler to 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.

I expect that 19.53125 will be rounded up to 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.

Upvotes: 0

Views: 558

Answers (2)

uncletall
uncletall

Reputation: 6842

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.

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/
  2. Why printf round floating point numbers?

Upvotes: 0

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38922

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; 1.5 rounds up to 2.

GCC C++ standard library applies the Bankers Rounding. 19.53125 -> 19.5312, since 2 is the nearest even digit.

Additional info regarding C, but C++ respects C rounding: C++ Rounding behavior consistency for ties with sprintf

Upvotes: 1

Related Questions