Why does `f64` print as many as 50 nonzero digits?


#1
fn main() {
    let a = 1.337f32;
    let b = 1.337f64;
    println!("{:.50}", a);
    println!("{:.50}", b);
}

You can run it at http://is.gd/SAJYBq. The output is:

1.33700001239776611328125000000000000000000000000000
1.33699999999999996624922005139524117112159729003906

Why does it print so many nonzero digits for f64?


#2

Because you asked it to print 50 digits.


#3

Either there’s a bug or 1.337 rounds to a finite decimal representation with 32 bits, but an infinite one at 64 bits.

Wait, a binary fraction can’t have an infinite decimal representation. The hell am I thinking?

Actually, if you ask it to print 2.0f64.pow(-52.0), that only terminates after 52 digits.


#4

1.3369999999999999999 is actually 1.337 (if we had infinite precision). But since 64bit floats only have something like 53 bits of precision, it has to end somewhere.


#5

Thanks! I get the point: 64bit floats only have something like 53 bits of precision.


#6

Every number has an infinite decimal representation. For example 1 == 0.999999…


#7

You’re splitting hairs; I’m talking about finite fractions as actually used by computers, not party tricks mathematicians use to confuse non-mathematicians.

Besides, everyone knows that 0.1 + 0.2 ≠ 0.3, so raspberries.