Integer-to-float cast may silently lose precision
ID |
rust.portability.cast_precision_loss |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Numeric Conversion |
Language |
Rust |
Description
Detects an as cast from an integer type whose range exceeds the destination float’s mantissa: anything wider than 24 bits cast to f32, and anything wider than 53 bits cast to f64, including the pointer-width usize and isize.
Rationale
A float stores only as many significant bits as its mantissa holds, so a large integer is rounded to the nearest representable value instead of being converted exactly. The result compares unequal to the original, and repeated conversions drift, which shows up as off-by-one totals and identifiers that collide after a round trip.
The following code illustrates the pattern detected by this rule:
pub fn ratios(total: u64, seen: i64, len: usize, id: u32, delta: i32) -> f64 {
// FLAGGED: Integer-to-float cast may silently lose precision
let a = total as f64;
// FLAGGED: Integer-to-float cast may silently lose precision
let b = seen as f64;
// FLAGGED: Integer-to-float cast may silently lose precision
let c = len as f64;
// FLAGGED: Integer-to-float cast may silently lose precision
let d = id as f32;
// FLAGGED: Integer-to-float cast may silently lose precision
let e = delta as f32;
// FLAGGED: Integer-to-float cast may silently lose precision
let f = total as f32;
a + b + c + d as f64 + e as f64 + f as f64
}