Executing this code (Playground):
println!("u128 max: {}", u128::max_value());
println!("f32 max: {}", std::f32::MAX);
println!("f32 as u128: {}", std::f32::MAX as u128);
... prints:
u128 max: 340282366920938463463374607431768211455
f32 max: 340282350000000000000000000000000000000
f32 as u128: 340282346638528859811704183484516925440
Judging from this output, we can deduce that u128::max_value() > f32::MAX
and that f32::MAX
is an integer (without fractional part). Indeed, Wikipedia agrees with the max values and says that f32::MAX
is (2 − 2−23) × 2127 which is slightly less than 2128. Given that, I would think that f32::MAX
is exactly representable as u128
. But as you can see, casting it via as
gives an entirely different value.
Why does the result of the cast differ from the original value?
(I know that floats are very strange beasts and all. But I hope that there is an answer to this question that contains more information than "floats are strange duh")
This is due to the formatting of the float when you are printing it. It seems by default the formatter will only show 8 significant figures when printing floats. Explicitly specifying the precision in the format string will yield the same results for line 2 and 3.
println!("u128 max: {}", u128::max_value());
println!("f32 max: {:.0}", std::f32::MAX);
println!("f32 as u128: {}", std::f32::MAX as u128);
Outputs:
u128 max: 340282366920938463463374607431768211455
f32 max: 340282346638528859811704183484516925440
f32 as u128: 340282346638528859811704183484516925440
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With