Some people advise not to compare floating-point numbers with equality operators (such as ==
or !=
), but this advice is misguided. The equality operators work as they should, without error. Better advice is more like this: Floating-point arithmetic operations (including conversion between types and conversion from numerals such as “5.5”) typically introduce rounding errors, so computed results of floating-point operations will typically differ from mathematically exact results. If you desire to determine whether two exact values modeled with approximate floating-point are equal or not, you should:
- Determine how much error there may be in the modeled values.
- Determine whether you can tolerate slightly different exact amounts being reported equal due to floating-point errors, and what amount of difference you can tolerate (false positives).
- Determine whether you can tolerate equal exact amounts being reported unequal due to floating-point errors (false negatives).
At the very least, you should estimate the above. Then determine whether there is a test you can perform that returns results with acceptably low rates of false positives and of false negatives. Commonly, people use a test such as fabs(a-b) < ErrorThreshold
and guess at the ErrorThreshold.
Guessing is not engineering.
The above is for equality. Similar concerns apply to comparing for order (e.g., <
or <=
).
For the sample you show, the question would be how much you care about characterizing numbers that are very near the borders of 5.5 and 9.7. Is it okay if numbers slightly above or slightly below the border are put into the correct category? If so, use the tests as you have them. If it is not okay, you need to explain your criteria further, along with information about how much error in $myfloat
there may be.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…