0

I have a software that does massive calculations on doubles and it has to run on linux and windows. I do not care about what behavior is used (faster is better), but it is mandatory that I get the same results on both platform.

I am compiling with x86_64-w64-mingw32 gcc version 4.9.2 on windows 10. And x86_64-linux-gnu gcc 4.9.3 on xubuntu.

I've tried using the following compile options: -frounding-math -fno-rounding-math -ffloat-store on both systems and nothing seems to work.

I know a bit about the complexity of floating-point representation but should it really be that hard to force the same behavior for a software that has to be cross platform?

HangrY
  • 139
  • 8
  • 2
    "nothing seems to work". Could you show some code? – wally Mar 21 '18 at 15:44
  • What exactly is behaving differently? – Sami Kuhmonen Mar 21 '18 at 15:47
  • No I cannot, sorry but code here isn't really relevant or reliable due to the size of the software and the number of calculations. With 3 days of digging I think it most likely comes from rounding and calculation precisions – HangrY Mar 21 '18 at 15:48
  • Have you considered integer math? or gmp signed integers? – 2785528 Mar 21 '18 at 15:48
  • I cant work on integers; although i'll take a look a gmp. For the same code running I don't have the same output on both systems – HangrY Mar 21 '18 at 15:49
  • 1
    Maybe try [checking](https://stackoverflow.com/a/5777610/1460794) if all your platforms use ieee 754 – wally Mar 21 '18 at 15:49
  • You have not mentioned [this very relevant flag](https://stackoverflow.com/questions/7420665). – Drew Dormann Mar 21 '18 at 15:51
  • 1
    Possible duplicate of [Cross Platform Floating Point Consistency](https://stackoverflow.com/questions/20963419/cross-platform-floating-point-consistency) – wally Mar 21 '18 at 15:54
  • What are your compilation flags? Are your inputs exactly the same? Are you using some external libraries? How much you results differ on both platforms? – Daniel Langr Mar 21 '18 at 15:54
  • You might also want to look at https://gmplib.org/, http://www.boost.org/doc/libs/1_66_0/libs/multiprecision/doc/html/index.html, or similar multiple precision libraries (https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software) if you care about reproducibility and not about performance. – Daniel Langr Mar 21 '18 at 16:00
  • Compiler flags are -std=c++11 -static-libgcc -static-libstdc++ -fexceptions So, not much The outputs are large because the software loops over the calculations and give results each time but the first difference that occurs is a 0.0000012 difference. After 300 iteration I have a difference too large to be ignored by my company's clients. – HangrY Mar 21 '18 at 16:01
  • yes both platforms use IEEE 754 – HangrY Mar 21 '18 at 16:05
  • @RichardCritten: The C++ standard specifies the order of evaluation in the [expr] clause. It does not fully determine the precision used for floating-point evaluation. – Eric Postpischil Mar 21 '18 at 16:24
  • @wally: Certainly this question is similar. Unfortunately, as floating-point behavior is not fully standardized, an answer for one set of compilers is not a duplicate of an answer for another set of compilers, even if they differ only in which versions they are. Getting deterministic behavior requires, among other things, setting certain compiler switches. – Eric Postpischil Mar 21 '18 at 16:26
  • 2
    Do you call any math library routines, such as `sin` or `log`? Do you have any multi-threading or other non-deterministic behavior in your program, aside from the floating-point? – Eric Postpischil Mar 21 '18 at 16:27
  • No multi threading but yes a few uses of math routines – HangrY Mar 21 '18 at 16:51
  • @EricPostpischil Why is it unfortunate? The duplicate doesn't claim to be version specific. "among other things" could mean anything. – wally Mar 21 '18 at 17:26
  • @wally: It is unfortunate because another question that is generic or that answers for other compilers or versions does not answer this question. And hence this question should not be marked as a duplicate of the other, since it is not a duplicate and is not answered by the other. – Eric Postpischil Mar 21 '18 at 17:35
  • @EricPostpischil This is not a version specific problem. – wally Mar 21 '18 at 18:00
  • @wally: It is a version-specific problem because solutions that work in one compiler version may not work in another version, due to changing behaviors between versions. Or there may have been no solution in a previous version (e.g., because the compiler did not offer a switch to select what precision was used in evaluating floating-point expressions) but there is in a later version (because a switch was added). – Eric Postpischil Mar 21 '18 at 18:13

1 Answers1

0

To have the same behavior, at least you have to:

1- standardize your type, do not switch from double to long double use only unique type long double for example 2- if you have any constante, use floating point literal related to your type:

If you choose long double, your constante must have as suffixe l or L ex: 0.5L

Ratah
  • 299
  • 3
  • 11
  • I only use double and I take all my data I work on from files, so no constants – HangrY Mar 21 '18 at 16:15
  • This answer is not nearly sufficient. Differences in floating-point behavior arise from compilers opting to use more precision (e.g. using `long double` calculations even when the type of the operands is `double`), compilers contracting expressions (replacing `a*b+c` with `fma(a, b, c)`), and otherwise taking license with floating-point arithmetic. Additionally, if a program is multithreading or otherwise non-deterministic in its execution, floating-point results may vary. Answering the question requires addressing specific compiler characteristics. – Eric Postpischil Mar 21 '18 at 16:21
  • I need 8-9 digits precision, and the first inconsistency that arises is at 10^-6 – HangrY Mar 21 '18 at 16:54
  • You have to trace where in your program you notice the beginning of inconsistency. It would be due to a particular computation or user-defined function. Otherwise try long double and notice the first inconsistency, it should be less than 10 digits precision – Ratah Mar 21 '18 at 17:32
  • The first inconsistency happens on the 12-13 digits but after 300 iteration I have a 15% difference on the final result (the approximations errors causes the program to go into if statement at different times on different systems). I need 10^-6 precision. A – HangrY Mar 21 '18 at 17:45