This test passed on Windows and many Linux computers. But in my Linux virtual machine on Windows computer, it failed:
---- test stdout ----
thread 'test' panicked at 'assertion failed: `(left == right)`
left: `1000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0`,
right: `1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0`', src/main.rs:7:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
The result of 10f64.powf(126.0) is 1.0000000000000001e126. I have tried this test in many Linux comupters, only this one failed.
All the computers have same Intel CPU. rustc is 1.52.1.
How can I solve this problem, or is there a reasonable explanation?
Are the Linux versions the same in that virtual machine vs. the native hosts? I suspect this comes down to the libm implementation of pow -- can you reproduce this with similar C code?
The two results differ by 1ULP. (You can see this yourself with Float Toy .) This is, in general, allowed for all the methods on floats, with a few exceptions for the basic things (+-*/%, and trivial methods like abs). Different math libraries are only expected to be within 1ULP of the correct answer, which mean there are 2 possible results they can give while still being correct, and different implementations will end up giving different values sometimes.
It's also worth noting that 1e126 is not precisely represented in f64, despite looking like a nice round number. If you factor that, 2126 is incorporated in the floating point exponent just fine, but the remaining 5126 is a 293-bit odd number, which can't be exactly represented by the 53-bit mantissa of f64.