How to confirm whether different results differ from differences in floating point processing?

I converted a relatively simple algorithm that performs a large number of calculations on double from C ++ to Java, however, the algorithm works on two platforms, but the same computer produces slightly different results. The algorithm multiplies and sums a lot of paired and ints. I force ints to double the Java algorithm; algorithm C is not applied.

For example, in one pass I get the results:

  • (Java) 64684970
  • (C ++) 65296408

(Printed to ignore decimal places)

Naturally, there may be a mistake in my algorithm, however, before I start spending time debugging, is it possible that the difference can be explained by floating-point processing in C ++ and Java? If so, can I prove that this is a problem?


An update β€” a place where types differ from each other β€” is a multiplication between two ints, which is then added to the current resulting double. By changing the C code, both are currently:

mydouble += (double)int1 * (double)int2

+6
source share
3 answers

AFAIK, there are times when a double literal value can change between two versions of the C ++ compiler (when the algorithm used to convert the source to the next best double value has changed).

Also, some cpus floating-point registers are larger than 64/32 bits (greater range and accuracy), and how this affects the result depends on how the compiler and JIT move the values ​​to and from these registers - this will probably be different between java and c ++.

Java has the strictftp keyword to ensure that only 64/32 bit precision is used, however this is time-consuming. There are also many possibilities to influence how C ++ compilers process and optimize floating point calculations, discarding the warranty / rules set by the IEEE standard.

if the algorithm is basically the same then you can check where the first difference appears for the same input.

+2
source

You can add rounding to each algorithm using the same precision. This will allow each calculation to process the data in the same way. If you use this, this will eliminate the algorithm, which is the problem, because the data will use the same precision at each step of the equation for C ++ and Java versions

+3
source

In Java, double is a 64-bit floating point number. In C ++, double is a floating point number guaranteed by at least 32-bit precision.

To find out the actual size in bytes of a C ++ double on your system, use sizeof (double).

If it turns out that sizeof (double) == 8, it is almost certain that the difference is due to an error in the translation from one language to another, and not due to differences in the processing of floating point numbers.

(Technically, the byte size is platform dependent, but most modern architectures use 8-bit bytes.)

+1
source

Source: https://habr.com/ru/post/909752/


All Articles