I am using gfortran in MinGW under Windows 7 (32bit) to compile Fortran code. Here is the minimal code contained in the file testequal.f
:
program testequal
real*8 a1, a2
a1 = 0.3d0
a2 = 0.7d0
write(*,*) 1.d0
write(*,*) a1+a2
write(*,*) a1+a2.eq.1.0
write(*,*) a1+a2.eq.1.d0
end
Compiled with
gfortran testequal.f -std=legacy
the output is:
1.0000000000000000
1.0000000000000000
F
F
But I expect the two booleans to be both T
(true). What is the problem here?
If the integer representations of two same-sign floats are subtracted then the absolute value of the result is equal to one plus the number of representable floats between them. In other words, if you subtract the integer representations and get one, then the two floats are as close as they can be without being equal.
Consider operator==, which returns true only if its operands are exactly equal. Because even the smallest rounding error will cause two floating point numbers to not be equal, operator== is at high risk for returning false when a true might be expected.
The Math. fround() function returns the nearest 32-bit single precision float representation of a Number. And therefore is one of the best choices to compare 2 floats.
The Problem Since real numbers cannot be represented accurately in a fixed space, when operating with floating-point numbers, the result might not be able to be fully represented with the required precision.
With rare exceptions, don't compare floating point numbers for exact equality. The rules of finite-precision floating point arithmetic are not the same are the rules of real number arithmetic. Compare numbers with a tolerance, e.g.,
sum = a1 + a2
if ( abs (sum - 1.0) < 1.0D-5 ) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With