on a floatingpoint equality exercise
a replytoall from the COMP1511 forums, 20170910
(I’ve been asked several times about how to do this, so here’s my official “all the bellsandwhistles” answer.)
Many of you have found that your apparentlycorrect myAtoD
causes an
assertion failure, because the value you’ve produced (typically
something like 0.14100000000000001) isn’t exactly 0.141. As is the
way with floatingpoint numbers, you’re off by a tiny, tiny fraction.
The problem with floatingpoint numbers is that they’re not exact
values, but a finite number of approximations of real numbers.
Inherently, two numbers that appear the same aren’t guaranteed to have
exactly the same pattern of bits set to represent that floatingpoint
number. C’s equality operator, ==
, does bitforbit comparison, so two
floatingpoint numbers won’t always compare equal.
If I make a quick sidestep to COMP1521 material: 0.141 actually
becomes 0.140999999999999986455279, which is stored as the bit pattern
0xBFC20C49BA5E353F
. The number you’re seeing is somewhere around
0.141000000000000014210855, which is stored as the bit pattern
0xBFC20C49BA5E3540
.
0xBFC20C49BA5E353F
!= 0xBFC20C49BA5E3540
On my system, when I go to compile the extract.c
provided, I get a
compiler warning for this exact reason:
extract.c:25:19: warning: comparing floating point with == or != is unsafe [Wfloatequal]
assert (dat.y == 0.141);
~~~~~ ^ ~~~~~~
One student on the forums has suggested that multiplying and dividing by 1000 produces a reasonable result. That might work… if there’s only three decimal places.
The way I’d do it is to explicitly check that the value is within a
range – that 0.142 < dat.y && dat.y < 0.140
. You might like to
write a function to do this.
If you’re interested in how numbers work, I highly recommend:

“What Every Computer Scientist Should Know About FloatingPoint Numbers”
(David Goldberg, in ACM’s Computing Surveys, March 1991)
http://docs.oracle.com/cd/E1995701/8063568/ncg_goldberg.html 
“How to Read FloatingPoint Numbers Accurately”
(William D. Clinger, in the proceedings of the 1990 ACM Conference on Programming Language Design and Implementation)
http://www.cesura17.net/~will/Professional/Research/Papers/howtoread.pdf 
“How to Print FloatingPoint Numbers Accurately”
(Guy L. Steele, Jon L. White; in the proceedings of the 1990 ACM Conference on Programming Language Design and Implementation)
https://lists.nongnu.org/archive/html/gcldevel/201210/pdfkieTlklRzN.pdf