News for hackers. Stuff that matters.
Re:Pretty.c by hmry on Thursday October 24, 2024 @04:33AM (#41933393)
This code is incorrect, but I don't blame them. :) Probably one of the most common float-related mistakes, even among people who "know how floats work".

FLT_EPSILON is the difference between 1.0 and the next larger float. It's impossible for numbers less than -2.0 or greater than 2.0 to have a difference of FLT_EPSILON, they're spaced too far apart.

You really want the acceptable error margin to be relative to the size of the two numbers you're comparing.

Also, everyone should read the paper "What, if anything, is epsilon?" by Tom7

Re:Pretty.c by aartaka on Thursday October 24, 2024 @07:10AM (#41934338)
Indeed, FLT_EPSILON is not a one-size-fits-all solution, but it's good enough for frequent case of comparing big enough numbers, which is not covered by regular ==. So it's a convenience/correctness trade-off I'm ready to make.
Re:Pretty.c by hmry on Thursday October 24, 2024 @09:02AM (#41935090)
If the numbers you are comparing are greater than 2, abs(a - b) < FLT_EPSILON is equivalent to a == b. Because it's not possible for two large numbers to not be equal, but also closer together than FLT_EPSILON.
Re:Pretty.c by jdthedisciple on Thursday October 24, 2024 @03:06PM (#41938645)
what

    // FLT_EPSILON == 0.01
    equal(4.999, 5); // true
    4.999 == 5;      // false
am i missing?
Re:Pretty.c by hmry on Thursday October 24, 2024 @03:52PM (#41939079)
FLT_EPSILON is not 0.01, it's 0.00000011920929.

But it's impossible to have a number that's 0.00000011920929 less than 5.0, or 0.00000011920929 more than 5.0, because the floats with enough magnitude to represent 5 are spaced further apart than that. Only numbers with magnitude < 2 are spaced close enough together.

In other words, the only 32-bit float that's within ±0.00000011920929 of 5.0 is 5.0 itself.

Re:Pretty.c by jdthedisciple on Thursday October 24, 2024 @04:19PM (#41939314)
Oh you're right, thanks for the explanation!

Gotta research now where the 0.00000011920929 number comes from...

Re:Pretty.c by masklinn on Thursday October 24, 2024 @04:27PM (#41939403)
It's the distance between 1.0 and the next representable float.
Re:Pretty.c by jdthedisciple on Thursday October 24, 2024 @04:47PM (#41939585)
I got that but I am curious how to derive that number.

Is it representable as a non-trivial ratio of integers?

Re:Pretty.c by hmry on Thursday October 24, 2024 @05:25PM (#41939960)
Good question! It's 1/(2**23), because 32 bit floats have 23 bits after the decimal point
Re:Pretty.c by im3w1l on Thursday October 24, 2024 @06:09AM (#41934018)
I would go even further and say that any equality comparison of float numbers has to be a one-off special case. You need to know how much error can arise in your calculations, and you need to know how far apart legitimately different numbers will for your particular data. And of course the former has to be smaller than the latter.