-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EPSILON is a bad error margin and should not be recommended [float_cmp] #6816
Comments
When I was still writing float-heavy code, I always had a function to calculate a suitable epsilon-value based on the values to compare and the number of mantissa bits that I expected to be equal. |
So then should we lint against |
This also has implications for |
I'm not completely certain. In cases where That said, I do think that To be extra pedantic, a pedantic lint against I don't have any strong opinions on linting float comparisons, though, beyond not recommending comparison against machine epsilon. |
The old classic "What Every Computer Scientist Should Know About Floating-Point Arithmetic" says that when a real number is rounded to the closest floating point number it's relative error is bounded by machine epsilon. Note that is relative error not absolute. So based on that I would expect the correct comparison to be |
Oh, it looks like |
This bad suggestion came up on URLO. |
This came up on IRLO again and will likely continue to do so until this is somehow categorically fixed. |
Is it that hard? The test should be:
where But before we do any of the above, consider alternatives:
|
Also, I'd say use |
A backward-stable algorithm evaluating a function |
[f32|f64]::EPSILON
are the machine epsilon of the type, or (as stated in the Rust docs), the distance between1.0
and the next representable floating point number.The page linked in the more info specifically says that
abs( a - b ) < epsilon
is wrong for any value ofespilon
. However, it's especially egregious withf__::EPSILON
, because for floating point numbers outside the range-2..=2
, floating point numbers cannot bef__::EPSILON
close, soabs( a - b ) < f__::EPSILON
is actually equivalent to a strict equality check.There isn't a generally applicable solution to recommend. The most thorough resource I've found suggests comparison in ULPs for testing against a non-zero number, and testing against a fixed epsilon (but one bigger than
f__::EPSILON
.At the least, we (and probably std) shouldn't be recommending comparing against
f__::EPSILON
, as it's basically as poor as bitwise equality and gives a false sense of handling the problem, when it isn't really handled.The text was updated successfully, but these errors were encountered: