I wondered whether the values 1/256, 2/256, 3/256, ... 254/256 and 255/256 are exactly representable as f32
. Now, someone smart would think about how floating point numbers work and find out that way. But I would like to check that in a program. All numbers I want to check are fractions and I control the values (i.e. no user input).
I started with this:
for n in 1u8..=255 {
let f = (n as f32) / 256.0;
println!("{}", f);
}
But now what? I tried printing the number to see if there were a large number of recurring digits, but that doesn't always work. For example, 0.4 which is not exactly representable:
println!("{}", 0.4); // prints "0.4"
println!("{:.20}", 0.4); // prints "0.40000000000000002220"
Here we have to manually crank up the precision to see the problems. And in any case, looking at the string output seems like a suboptimal solution anyway.
First I thought that there might be a method on f32
, but this wouldn't make much sense, would it? Because when a f32
already exists, there is no way to know if its value was intended or not. So we somehow have to find out when creating the float value and compare to the "idealized" value?
Is there any way to check if a value can be exactly represented as f32
?