Root cause: accumulation of floating point rounding error combined with a tolerance on the equality check
Lesson: use exact equality checks with floating point numbers
Oh please don’t. This will bite you far more often than the example in the video. You’ll be totally scratching your head wondering why
x = 0.1
y = 0.2
z = 0.3
if (x + y == z) print *, "Success!"
doesn’t seem to work.
0.1 is not 0.1,
but 0.125 is 0.125.
If you watch the video, the real problem seems to be a form of race condition. There are two flags, one that is set with a tolerance and one that is not.
Oh the finitely countable joys of floating point numbers!
Note that I posted that on April 1st (at least in my timezone).
phew I didn’t read it till after, so wasn’t sure.
Yes writing sophisticated code like this
real(REAL64) :: a
real :: b
If ((a-b) == 0.0) then
a = 1.0
b = 2
End If
is best left to us experienced programmers
Surprisingly, I still see nonsense like this in codes written in the last few years by people who should know better.
Isn’t this a result of the fact tha 0.125 can be exactly represented in binary but 0.1 don’t?
Yes :
- 0.125 = 1/8 = 0b0.001
- 0.1 = 1/10 = 0b0.0001100110011001101…
A number with a finite number of digits in a base can have an infinite number of digits in another base.
But if there is a finite number of digits in binary, there should always be a finite number in decimal, as it is a sum of 1/2^n. But in other bases?
Dont know the answer, but I think with larger bases there are more number that can be represented exactly.
It sounds reasonable.
I guess it’s a matter of prime factors in the base. Base two has only one prime factor and therefore can only exactly represent numbers which can be represented as the sum \sum_{k=m}^{n} a_k2^k.
Base ten has two prime factors: 2 and 5. Therefore, every number, that can be represented exactly with a finite amount of digits with base two, can be represented exactly with base 10, but not the other way around.
Makes a lot of sense