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

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

You can run it at Rust Playground. The output is:

1.33700001239776611328125000000000000000000000000000
1.33699999999999996624922005139524117112159729003906

Why does it print so many nonzero digits for f64?

Because you asked it to print 50 digits.

3 Likes

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.

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.

3 Likes

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

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

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.

1 Like