-
Notifications
You must be signed in to change notification settings - Fork 9
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
List of operations that produce NaN? #29
Comments
Thanks for raising this up. I will think about adding the NaN cases to the documentation (as I'm writing a guide to be published with the release v0.4). Currently as not many operations are implemented for the FBig type, the potential sources of NaNs are:
Common approach to make user aware of NaNs includes:
I think providing a good documentation and let the user handle corner cases is the way to go. |
Another source of panics are overflow/underflow. For example, the following, which underflow panics instead of rounding down: FBig::<Down>::try_from(-6871947604880523000.)?.exp() |
It's also not possible to anticipate settings where the calculation might overflow. Take for example, the following, which panics: let lhs = f64::MAX;
let rhs = f64::MIN_POSITIVE;
FBig::<Up>::try_from(lhs)? + FBig::<Up>::try_from(rhs)? However, the naive check you might run beforehand doesn't anticipate the issue: if (lhs + rhs).is_finite() {
// dashu code here still runs and panics
return Ok(FBig::<Up>::try_from(lhs)? + FBig::<Up>::try_from(rhs)?)
} For my own use, I've wrapped the dashu API with catch unwind and panic handlers. |
Well the underflowing/overflowing cases are indeed hard to catch them all beforehand, I'm open to provide a fallible API for this case. My main concern is to add I have several viable options in mind, although none of them is perfect:
Please let me know which approach looks best to you, or if you have better ideas! Thanks! @kameko @Shoeboxam |
My favorite over the three is the last one, and when implemented as methods of |
All of these options strike me as viable solutions. Comments on each approach, respectively:
I think all three approaches are somewhat similar- instead of pushing infinity/nan into a panic, you are packing it into a struct- either within a Which approach is better depends on what you want your library to support: Right now the library doesn't allow nan/inf inputs or outputs. If you want the library to support only nan/inf outputs, then I'd pack those states into a result. If you want the library to support nan/inf inputs and outputs, like MPFR, then those states should be in your data type. |
Regarding nan/inf, I don't plan to support them as input. Operations on nan/inf are mathematically ill-defined, and they exists in programming because the precision is limited in computers. In my opinion, they are mostly useless when you want to do arbitrary precision operations. It's better to stick to f32/f64 when you find that you encounter nan/inf pretty often. |
Making the ops associated with |
The documentation for dashu_float says that operations that produce NaN will panic. I'd like to be able to check for such conditions before performing those operations, so I can catch them and return Err instead. However, I don't know all possible operations that can panic, and the source code doesn't make it obvious. I'm checking for the obvious right now in my code, checking for any operations that work with infinity, etc.. But I think the documentation should specifically list every operation that can panic.
Additionally, it would be nice if the standard library actually had some kind of
would_panic
orresults_in_nan
function to explicitly check that for you, or stuff liketry_div
ortry_mul
, etc., but I'm just thinking out loud.The text was updated successfully, but these errors were encountered: