-
Notifications
You must be signed in to change notification settings - Fork 13.4k
<{f16,f32,f64,f128} as Rem>::rem
documented definition is misleading w.r.t. intermediate rounding
#133758
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Notably, and perhaps uncoincidentally, C's
...and the same mismatch: unsafe extern "C" {
safe fn fmod(x: f64, y: f64) -> f64;
}
fn main() {
let (x, y) = (11f64, 1.1f64);
assert_eq!(x - (x / y).trunc() * y, fmod(x, y));
//~^ PANIC
// assertion `left == right` failed
// left: 0.0
// right: 1.0999999999999992
} |
Indeed, Rust's floating point |
Yes, and the C docs state it even more clearly. They say, "it is exactly the value...". |
Yes, it is mathematically exact:
(sorry, the numbers get rather large with IMO, this is a bug in the documentation. Float |
|
edit: I misinterpreted the C standard. See the next message. So,
(in addition to the exact result of
|
No, this is incorrect. The exact value is the only value that is allowed by the C standard (for an implementation that supports IEEE-754 with subnormals), as specified by F.10.7.1:
The C expression
That's a mathematical formula, not a C expression (as is clear by the lack of a |
Agreeing and extending, IEEE 754-2008 says in 5.3.1:
Then C23 F.10.7.1 says:
So, for 11 and 1.1, remainder(11., 1.1) = exact!(11. - 1.1 * 10.) = -10f64.mul_add(1.1, -11.) = -0.0000000000000008881784197001252;
fmod(11., 1.1) = remainder(11., 1.1) + 1.1 = 1.0999999999999992; |
Hello @traviscross , I am interested to work on this issue to fix |
This is a duplicate of #107904. |
Actually, I don't think this is a duplicate of that. This is a separate documentation bug. We just need to say explicitly in the docs that the stated calculation, |
OK but then title of the issue should be clarified. |
<{f16,f32,f64,f128} as Rem>::rem
are not remainder of truncated division, as documented<{f16,f32,f64,f128} as Rem>::rem
documented definition is misleading w.r.t. intermediate rounding
Uh oh!
There was an error while loading. Please reload this page.
Our documentation for
impl Rem for {f16, f32, f64, f128}
says:But that's not true. E.g.:
This mismatch creates a hazard when trying to correctly encode algorithms that rely on this semantic.
This tripped me up, e.g., when authoring:
{f16,f32,f64,f128}::div_euclid
#133755cc #133485 #107904
cc @cuviper @Noratrieb @tczajka @Neutron3529 @BartMassey
The text was updated successfully, but these errors were encountered: