1

My C++ program calculates some floating-point number x and prints it:

cout << x;

It is important to me that the output be the same in all computers. Since "all" is very broad, let's focus on the following:

  • different compilers from among g++ 6/7/8, clang++ 5/6;
  • different Linux systems - Ubuntu 16.04/18.04;
  • stand-alone Linux vs. Windows-subsystem Linux;
  • different hardware - Intel vs. AMD with different specs.

Is the output guaranteed to be the same in all the above combinations?

If not, can I guarantee identical output by lowering the precision, e.g:

cout << setprecision(4) << x;

? If not, what more can I do to have consistent output across machines?

Clifford
  • 88,407
  • 13
  • 85
  • 165
Erel Segal-Halevi
  • 33,955
  • 36
  • 114
  • 183
  • `printf` with %.xf – Michael Chourdakis Apr 04 '19 at 17:17
  • 4
    You may find these three links of interest: 1) [Floating-Point Determinism](https://www.google.com/amp/s/randomascii.wordpress.com/2013/07/16/floating-point-determinism/amp/) , 2) [What Every Computer Scientist Should Know About Floating-Point Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) , 3) [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) . – Jesper Juhl Apr 04 '19 at 17:19
  • 2
    Floating-point math is all about being **fast**. Getting precisely specified results isn't fast. Java tried to require all implementations to use IEEE 64-bit floating-point for `double`; serious users rebelled because it was so slow (Intel hardware is tuned for 80-bit calculations, and 64-bit doubles are widened to 80 bits for calculations), and Java now has "strict" math that nobody uses, and ordinary math which serious FP folks use. – Pete Becker Apr 04 '19 at 17:22
  • 1
    _@Erel_ I don't think it's guaranteed _cross platform_ to get consistent results, but that finally depends on how floating point values are represented with the underlying FPU architecture. Conclusion: Don't rely on consistent FP representations ever. Use _epsilon approximation_ instead. – πάντα ῥεῖ Apr 04 '19 at 17:31
  • Is this question just about whether `cout` is guaranteed to print the exact same `float` in the exact same way every time on all these different systems, or does the question include whether `x` will be computed to come out as exactly the same value on all of them? If it's about the latter, we'll have to know how `x` is computed. However, I can already tell you that, in that case, the answer is almost certainly: no. – Michael Kenzel Apr 04 '19 at 17:33
  • @MichaelKenzel I am only interested in generating the same output. – Erel Segal-Halevi Apr 04 '19 at 17:42
  • @ErelSegal-Halevi I think that this involves some rounding calculations being applied [under the hood](https://en.cppreference.com/w/cpp/locale/num_put/put). – πάντα ῥεῖ Apr 04 '19 at 17:50
  • The same compiler on the same platform, same hardware, same OS, will generate different results if passed different flags. – Ben Voigt Apr 04 '19 at 18:20
  • Stack Overflow seems to have a limit of listing five originals. Others include [this](https://stackoverflow.com/questions/32934019/are-floating-point-errors-deterministic), [this](https://stackoverflow.com/questions/11490038/floating-point-processor-non-determinism), and [this](https://stackoverflow.com/questions/9613301/how-can-i-get-consistent-program-behavior-when-using-floats). – Eric Postpischil Apr 04 '19 at 19:26

1 Answers1

2

Is the output guaranteed to be the same in all the above combinations?

No.

Very little about floating point representation is guaranteed by the C++ standard.

can I guarantee identical output by lowering the precision, e.g:

cout << setprecision(4) << x;

No.

If the accurate result of the calculation would be just at the border of rounding direction, then an arbitrarily small difference between the calculation could change the result. Rounding would magnify the difference between the calculations.

If not, what more can I do to have consistent output across machines?

  • Use something other than hardware floating point. Either software floating point or fixed point arithmetic.
  • Either use fixed width integers to implement that arithmetic so that one system doesn't have more precision than another, or use arbitrary precision.
  • If not using arbitrary precision, then only use expressions whose order of evaluation is defined by the language, so that differences between compiler don't result in different amounts of error.
Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326