Hi,
New to rust. Actually try to learn rust. I have some background in c++.
While read the documentation I try to make small programs to learn faster and more efficiently.
Didn't find a way to compare floating point numbers with std crates and decide to write my own
use std::num;
trait FloatComparator {
fn equal(self, other : Self) -> bool;
}
impl<T: impl Float> FloatComparator for T {
fn equal(self, other : Self) -> bool
{
Self::abs(self - other) <= T::EPSILON
}
}
Not sure if this is the right direction but while internet says that there should be trait Float in std::num my version of rust says that such a thing do not exist.
Can you explain me how to achieve that thing in proper way (compare floating points number)
And also tell me how to define generic trait that accept types that implement certain trits
According to the IEEE 754 floating-point standard, floating-point numbers cannot be compared equal because of NaNs, which according to the standard can't be compared. That's why there is no equal operator for floating point, in Rust or C or any other language that conforms to the standard.
No, you can compare them but it's not good idea because of the inherit error in them.
The best way to compare two floats is by abs(a - b) <= epsilone where epsilon is the expected error.
Nan are rare occurrence and usually you can check for that. Also if you have nan in your calculation you probably done some terribly wrong
You can't choose what types generic function will accept. They're always open to any type, and all you can do is to require these types to implement some traits.
There's num-traits that predefines some traits for numeric types, but programming this way can get awkward. Consider creating a macro instead. Rust macros behave more like C++ templates.
It look like you are not so much into computer computer science (no offence).
Fast google search can you lead here. https://floating-point-gui.de/errors/comparison/
The reason for floating point comparison to not work as expected a.k.a a == b and yeas there is complication coming from nans if your algorithm expect nan it should check for them anyway and trow an error because any operation with nan operand is ill and return nan and nan is not very useful result.
I'm not sure if I understand you but i'm pretty sure that I can restrict function parameters to types that implement certain traits. There is syntax like
Yes that perfect. It's even better than c++ equivalent. Do you know if and how I can define trait and make generic implementation that affect certain traits ?
I mean you can create a trait like Float and use it as a bound, but (apart from some clever tricks) you can't stop anyone from implementing Float for their string type if they want to. And the language and the compiler will behave as if anyone could implement that trait on anything at any time.
You'd do well not to draw premature conclusions. You're wrong, I have a formal background in CompSci.
Regardless, that doesn't mean that using arithmetic (which is explicitly defined on numbers) on something that is explicitly not a number (that's what NaN means, btw) is a sound thing to do. Or, you know, even a sane thing to do.
To be clear, the floating point specification says that NaN - NaN = NaN. You could think of it as "invalid value - invalid value still gives an invalid value"
Please understand my point, which is not that I want to compare non-NaN floats. In fact I regard that as a solved issue.
The point is that that issue is caused by something more fundamental, which is the standard itself. Now I understand why they added NaN in the first place (which is to allow the division 0/0 to return some kind of result) but it causes issues down the line because NaN isn't even what it's used as nonetheless: a number.
dude I don't wanna be rude but you have to understand that nan is 1) checkable and 2) you should check for it because any operation with nan is not valid operation not only ==, that include +,-, <, > and so on.
The reason that == is not good idea is not nans but rounding error
That's perfect. Did you know if I can make generic implementation of trait that effect anything that have Float or whatever. This is the main thing that I want to learn. If you know can you place simple example
Hundreds of professional PhD numerical analysts who contributed to or reviewed the IEEE 754 Floating Point standard would not agree with you. There is no ONE solution that satisifes all needs. If your experience with floating point predates the IEEE 754 standard, or included the early days of not-quite-conforming implementations, you probably would view the standard as a great advance on the state of the art, as I do.
Some of the predecessors to IEEE 754 were unbelievably bad. The worst was probably the hexadecimal-base floating point of the IBM 360 series, in which even trivial algorithms like Newton-Raphson iteration to compute a square root could fail to converge.
It is true that, relative to current technology, the handling of NaNs in IEEE 754 leaves a lot to be desired. However, so do other technologies of that prior era, including most of the languages that Rust can supercede.