diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index a3d70f31f002..a1362f1ff20c 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -127,11 +127,19 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { } } +/// The maximum number of significant decimal digits a float can contain. +/// f32: 23+1 bit significand, storing 6 to 9 decimal digits +/// f64: 52+1 bit significand, storing 15 to 17 decimal digits +/// Above the range's lower bound, precision in the decimal string may be lost, +/// but it is recommended to use the maximum number of digits, not the minimum, +/// when feeding these to a parser, as it preserves the accuracy in binary. +/// In addition, suggesting someone truncate an 8 decimal digit string +/// may change the result of the program if they apply it. #[must_use] fn max_digits(fty: FloatTy) -> u32 { match fty { - FloatTy::F32 => f32::DIGITS, - FloatTy::F64 => f64::DIGITS, + FloatTy::F32 => 9, + FloatTy::F64 => 17, } } diff --git a/tests/ui/excessive_precision.fixed b/tests/ui/excessive_precision.fixed index bf0325fec792..8ff9d742bd22 100644 --- a/tests/ui/excessive_precision.fixed +++ b/tests/ui/excessive_precision.fixed @@ -8,18 +8,22 @@ fn main() { const GOOD32_SM: f32 = 0.000_000_000_1; const GOOD32_DOT: f32 = 10_000_000_000.0; const GOOD32_EDGE: f32 = 1.000_000_8; + // the Kahan Krew wuz here + const GOOD32_IEEE754_1: f32 = 0.123_456_789_f32; + const GOOD32_IEEE754_2: f32 = 0.123_456_789; + const GOOD32_IEEE754_3: f32 = 1.000_000_9; + + const BAD32_1: f32 = 0.1; + const BAD32_2: f32 = 0.123_456_79; + const GOOD64: f64 = 0.123_456_789_012; const GOOD64_SM: f32 = 0.000_000_000_000_000_1; const GOOD64_DOT: f32 = 10_000_000_000_000_000.0; + const GOOD64_IEEE754_1: f64 = 0.123_456_789_012_345_67f64; + const GOOD64_IEEE754_2: f64 = 0.123_456_789_012_345_67; - const BAD32_1: f32 = 0.123_456_79_f32; - const BAD32_2: f32 = 0.123_456_79; - const BAD32_3: f32 = 0.1; - const BAD32_EDGE: f32 = 1.000_001; - - const BAD64_1: f64 = 0.123_456_789_012_345_66_f64; - const BAD64_2: f64 = 0.123_456_789_012_345_66; - const BAD64_3: f64 = 0.1; + const BAD64_1: f64 = 0.1; + const BAD64_2: f64 = 0.123_456_789_012_345_68; // Literal as param println!("{:?}", 8.888_888_888_888_89); @@ -37,16 +41,16 @@ fn main() { let bad32_suf: f32 = 1.123_456_8_f32; let bad32_inf = 1.123_456_8_f32; - let bad64: f64 = 0.123_456_789_012_345_66; - let bad64_suf: f64 = 0.123_456_789_012_345_66_f64; - let bad64_inf = 0.123_456_789_012_345_66; + let bad64: f64 = 0.123_456_789_012_345_67; + let bad64_suf: f64 = 0.123_456_789_012_345_67f64; + let bad64_inf = 0.123_456_789_012_345_67; // Vectors - let good_vec32: Vec = vec![0.123_456]; - let good_vec64: Vec = vec![0.123_456_789]; - + let good_vec32: Vec = vec![0.123_456_789]; let bad_vec32: Vec = vec![0.123_456_79]; - let bad_vec64: Vec = vec![0.123_456_789_123_456_78]; + + let good_vec64: Vec = vec![0.123_456_789_012_345_67]; + let bad_vec64: Vec = vec![0.123_456_789_012_345_68]; // Exponential float notation let good_e32: f32 = 1e-10; diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index ce4722a90f90..880a1596c346 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -8,18 +8,22 @@ fn main() { const GOOD32_SM: f32 = 0.000_000_000_1; const GOOD32_DOT: f32 = 10_000_000_000.0; const GOOD32_EDGE: f32 = 1.000_000_8; + // the Kahan Krew wuz here + const GOOD32_IEEE754_1: f32 = 0.123_456_789_f32; + const GOOD32_IEEE754_2: f32 = 0.123_456_789; + const GOOD32_IEEE754_3: f32 = 1.000_000_9; + + const BAD32_1: f32 = 0.100_000_000_000_1; + const BAD32_2: f32 = 0.123_456_789_012; + const GOOD64: f64 = 0.123_456_789_012; const GOOD64_SM: f32 = 0.000_000_000_000_000_1; const GOOD64_DOT: f32 = 10_000_000_000_000_000.0; + const GOOD64_IEEE754_1: f64 = 0.123_456_789_012_345_67f64; + const GOOD64_IEEE754_2: f64 = 0.123_456_789_012_345_67; - const BAD32_1: f32 = 0.123_456_789_f32; - const BAD32_2: f32 = 0.123_456_789; - const BAD32_3: f32 = 0.100_000_000_000_1; - const BAD32_EDGE: f32 = 1.000_000_9; - - const BAD64_1: f64 = 0.123_456_789_012_345_67f64; - const BAD64_2: f64 = 0.123_456_789_012_345_67; - const BAD64_3: f64 = 0.100_000_000_000_000_000_1; + const BAD64_1: f64 = 0.100_000_000_000_000_000_1; + const BAD64_2: f64 = 0.123_456_789_012_345_678_9; // Literal as param println!("{:?}", 8.888_888_888_888_888_888_888); @@ -42,11 +46,11 @@ fn main() { let bad64_inf = 0.123_456_789_012_345_67; // Vectors - let good_vec32: Vec = vec![0.123_456]; - let good_vec64: Vec = vec![0.123_456_789]; + let good_vec32: Vec = vec![0.123_456_789]; + let bad_vec32: Vec = vec![0.123_456_789_012]; - let bad_vec32: Vec = vec![0.123_456_789]; - let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; + let good_vec64: Vec = vec![0.123_456_789_012_345_67]; + let bad_vec64: Vec = vec![0.123_456_789_012_345_678_9]; // Exponential float notation let good_e32: f32 = 1e-10; diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index 599773f2f70c..e80a1c8e05a5 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -1,112 +1,76 @@ -error: float has excessive precision - --> $DIR/excessive_precision.rs:15:26 - | -LL | const BAD32_1: f32 = 0.123_456_789_f32; - | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79_f32` - | - = note: `-D clippy::excessive-precision` implied by `-D warnings` - error: float has excessive precision --> $DIR/excessive_precision.rs:16:26 | -LL | const BAD32_2: f32 = 0.123_456_789; - | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` - -error: float has excessive precision - --> $DIR/excessive_precision.rs:17:26 - | -LL | const BAD32_3: f32 = 0.100_000_000_000_1; +LL | const BAD32_1: f32 = 0.100_000_000_000_1; | ^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` - -error: float has excessive precision - --> $DIR/excessive_precision.rs:18:29 | -LL | const BAD32_EDGE: f32 = 1.000_000_9; - | ^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.000_001` + = note: `-D clippy::excessive-precision` implied by `-D warnings` error: float has excessive precision - --> $DIR/excessive_precision.rs:20:26 + --> $DIR/excessive_precision.rs:17:26 | -LL | const BAD64_1: f64 = 0.123_456_789_012_345_67f64; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66_f64` +LL | const BAD32_2: f32 = 0.123_456_789_012; + | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` error: float has excessive precision - --> $DIR/excessive_precision.rs:21:26 + --> $DIR/excessive_precision.rs:25:26 | -LL | const BAD64_2: f64 = 0.123_456_789_012_345_67; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66` +LL | const BAD64_1: f64 = 0.100_000_000_000_000_000_1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` error: float has excessive precision - --> $DIR/excessive_precision.rs:22:26 + --> $DIR/excessive_precision.rs:26:26 | -LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` +LL | const BAD64_2: f64 = 0.123_456_789_012_345_678_9; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_68` error: float has excessive precision - --> $DIR/excessive_precision.rs:25:22 + --> $DIR/excessive_precision.rs:29:22 | LL | println!("{:?}", 8.888_888_888_888_888_888_888); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` error: float has excessive precision - --> $DIR/excessive_precision.rs:36:22 + --> $DIR/excessive_precision.rs:40:22 | LL | let bad32: f32 = 1.123_456_789; | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8` error: float has excessive precision - --> $DIR/excessive_precision.rs:37:26 + --> $DIR/excessive_precision.rs:41:26 | LL | let bad32_suf: f32 = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32` error: float has excessive precision - --> $DIR/excessive_precision.rs:38:21 + --> $DIR/excessive_precision.rs:42:21 | LL | let bad32_inf = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32` error: float has excessive precision - --> $DIR/excessive_precision.rs:40:22 - | -LL | let bad64: f64 = 0.123_456_789_012_345_67; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66` - -error: float has excessive precision - --> $DIR/excessive_precision.rs:41:26 - | -LL | let bad64_suf: f64 = 0.123_456_789_012_345_67f64; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66_f64` - -error: float has excessive precision - --> $DIR/excessive_precision.rs:42:21 - | -LL | let bad64_inf = 0.123_456_789_012_345_67; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66` - -error: float has excessive precision - --> $DIR/excessive_precision.rs:48:36 + --> $DIR/excessive_precision.rs:50:36 | -LL | let bad_vec32: Vec = vec![0.123_456_789]; - | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` +LL | let bad_vec32: Vec = vec![0.123_456_789_012]; + | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` error: float has excessive precision - --> $DIR/excessive_precision.rs:49:36 + --> $DIR/excessive_precision.rs:53:36 | -LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_123_456_78` +LL | let bad_vec64: Vec = vec![0.123_456_789_012_345_678_9]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_68` error: float has excessive precision - --> $DIR/excessive_precision.rs:53:24 + --> $DIR/excessive_precision.rs:57:24 | LL | let bad_e32: f32 = 1.123_456_788_888e-10; | ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8e-10` error: float has excessive precision - --> $DIR/excessive_precision.rs:56:27 + --> $DIR/excessive_precision.rs:60:27 | LL | let bad_bige32: f32 = 1.123_456_788_888E-10; | ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8E-10` -error: aborting due to 18 previous errors +error: aborting due to 12 previous errors