The operator overlooks my pet peeve when it comes to comparing floating-point numbers: in C++ the "standard associative containers" (std::set and std::map) are based on ordering using an less-than relationship which must be a "strict weak ordering". Many times, the methods suggested for comparing floating point types do not satisfy the requirements of "strict weak ordering", and in this case the C++ standard says you…
Comparing Floating-Point Numbers Is Tricky
41–45 of 45 posts
Re: Comparing Floating-Point Numbers Is Tricky
#42Here's my less-than-scientific floating point near-equality test I use. bool zero(float x) ( return x*x This checks equality to about four decimal digits for 32 bit single precision and seven digits for 64 bit floats. Inf/NaN special values are not considered. Critique and comments welcome.
A better comparison would check for zero somehow like this:
bool zero(float x) { return std::abs(x) Re: Comparing Floating-Point Numbers Is Tricky
#43Re: Comparing Floating-Point Numbers Is Tricky
#44Here's my less-than-scientific floating point near-equality test I use. bool zero(float x) ( return x*x This checks equality to about four decimal digits for 32 bit single precision and seven digits for 64 bit floats. Inf/NaN special values are not considered. Critique and comments welcome.
`FLT_EPSILON` represent the minimum difference between two adjacent floats around 1.0; it should be scaled according to the input argument. E.g. your `equal_float` returns `true` for 2e-6 and 4e-6 which are clearly not the same number. A better comparison would check for zero somehow like this: bool zero(float x) { return std::abs(x)
I typically use this with doubles and DBL_EPSILON, which is much much smaller than FLT_EPSILON.
With FLT_EPSILON this roughly equals to "zero" being "less than 0.001". If the zero check is omitted, there's going to be a division by near-zero which will make the results nonsense (and you have to draw the line somewhere). With DBL_EPSILON "zero is less than 0.000000001".
If this is too loose, then `zero(x) = abs(x) This is good enough for my purposes, I don't deal with very small numbers in float and doubles give more than enough precision.
NOTE: I usually use this kind of comparison in testing by comparing known "gold" figures against the results of the code being tested. I don't test accuracy, I test for "in the ballpark" because the stuff I deal with has built-in inaccuracy in the algorithm and numerics.
The version you posted will always return false if I read it correctly.
Re: Comparing Floating-Point Numbers Is Tricky
#45The hard part is understanding when it is appropriate to compare floating point numbers and how to produce them.
I regularly use floating point numbers as keys in dictionaries and of course all the code quality tools whine about comparisons being inexact. But in my case there is no fuzziness because the keys are all produced by the same method and hence do not suffer from any different rounding errors.
Pretty much every new member of the team sees floats being compared and has heart attack yet the code in question is in the oldest and most reliable component of the whole million line program.
Just don't expect two numbers produced by different expressions that would be mathematically equivalent but have operators in a different order to produce identical results.