Skip to content

Decimal formatting for some floating point numbers does not round-to-even #130936

Open
@gregates

Description

@gregates

I have discovered a class of f64 for which format!("{}", f) rounds ties up to 3, rather than down to 2 as expected. Formatting those same numbers with fixed precision correctly rounds ties to even.

Here is some code that demonstrates the discrepancy:

fn main() {
    let fs: [f64; 15] = [
        112171935477118.12,
        181681934355391.62,
        -581170764721946.2,
        131673329546813.62,
        711901304153173.2,
        91266877191838.12,
        18406814307348.312,
        -620793498637746.2,
        -889345962364809.2,
        -664193405104534.2,
        -157386457699813.12,
        566922914748074.2,
        223437609802779.12,
        945017102864441.2,
        32461450983719.062,
    ];

    for f in fs {
        let no_precision = format!("{}", f);
        let mut split = no_precision.split('.');
        let _int = split.next();
        let frac = split.next().unwrap();
        let precision = frac.len();
        println!("{} != {:.2$}", f, f, precision);
    }

This program prints:

112171935477118.13 != 112171935477118.12
181681934355391.63 != 181681934355391.62
-581170764721946.3 != -581170764721946.2
131673329546813.63 != 131673329546813.62
711901304153173.3 != 711901304153173.2
91266877191838.13 != 91266877191838.12
18406814307348.313 != 18406814307348.312
-620793498637746.3 != -620793498637746.2
-889345962364809.3 != -889345962364809.2
-664193405104534.3 != -664193405104534.2
-157386457699813.13 != -157386457699813.12
566922914748074.3 != 566922914748074.2
223437609802779.13 != 223437609802779.12
945017102864441.3 != 945017102864441.2
32461450983719.063 != 32461450983719.062

Meta

rustc --version --verbose:

rustc 1.83.0-nightly (2bd1e894e 2024-09-26)
binary: rustc
commit-hash: 2bd1e894efde3b6be857ad345914a3b1cea51def
commit-date: 2024-09-26
host: x86_64-unknown-linux-gnu
release: 1.83.0-nightly
LLVM version: 19.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-floating-pointArea: Floating point numbers and arithmeticA-fmtArea: `core::fmt`C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions