Error in my floating point or gcc code?

The following code works as expected, for me under 64-bit, but with an error under the 32-bit value -O2 and -O3, the expected result is 1.1, under the systems we are listening - 1.0. I am trying to establish if this is a mistake in my code (which makes some bad assumptions about how floats work) or in GCC. If it is in my code, how can I fix it?

#include <math.h> #include <stdio.h> int f(double x) { return isinf(1.0 / x); } int m_isinf(double x) { return x != 0 && x * 0.5 == x; } int g(double x) { return m_isinf(1.0 / x); } double values[] = { 5.5e-309, -1.0 }; int main() { int i; for (i = 0; values[i] != -1.0; i++) { printf("%d\n", f(values[i])); printf("%d\n", g(values[i])); } return 0; } 
+4
source share
4 answers

An expression can be evaluated with greater accuracy than a type. In your 32-bit assembly, the compiler probably uses a double bit of 80 bits (which is no longer used in 64 bits) to evaluate x != 0 && x * 0.5 == x .

(GCC knows the problems with these rules, evaluating more accurately in a context where it cannot).

6.3.1.8/2 in C99 (6.2.1.5 in C90 is equivalent):

The values โ€‹โ€‹of floating operands and the results of floating expressions can be represented in greater accuracy and range than required by the type; types are not changed that way

In the appropriate implementation:

 int m_isinf(double x) { double const half_x = x * 0.5; return x != 0 && half_x == x; } 

must work. But the gcc bug ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 considers the number of duplicates) often prevents this from working. There are some problems in the error report.

+3
source

In principle, using equality comparisons on floats and doublings is the sure way to unexpected behavior.

+2
source

You can directly check the value, for example:

 #include <math.h> int isinf(double d) { union { unsigned long long l; double d; } u; ud=d; return (ul==0x7FF0000000000000ll?1:ul==0xFFF0000000000000ll?-1:0); } 

Courtesy of Dietetics

+1
source

Take a look at this for floating point control http://cibak.web.cern.ch/cibak/pval/valid.html

0
source

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


All Articles