-
Notifications
You must be signed in to change notification settings - Fork 981
Open
Description
Background
- Current behavior: the latest commit in Fix panic on lossy decimal to float casting: round to saturation for overflows #7887 removed the panic on overflow and now saturates any out-of-range
Decimal256
→Float64
conversions tof64::INFINITY
orf64::NEG_INFINITY
. - Why that’s sub-optimal: although this avoids crashes, it still injects infinities for large values—yet in fact every 256-bit integer fits in f64’s exponent range (±2¹⁰²³). We only ever lose precision in the mantissa, never dynamic range.
Proposal
Override ToPrimitive::to_f64
for i256
so that:
- No panics (we’ll never call
.unwrap()
or fall through toNone
). - No infinities—every value maps to a finite, rounded
f64
. - Behavior matches Rust’s built-in
(i128) as f64
logic: ties-to-even rounding, full exponent coverage.
Suggested implementation in arrow-buffer/src/bigint/mod.rs
impl ToPrimitive for i256 {
fn to_f64(&self) -> Option<f64> {
// Handle the one case where abs() would overflow: i256::MIN
let mag = if let Some(abs) = self.checked_abs() {
// Break the magnitude into (low: u128, high: i128)
let (low, high) = abs.to_parts();
// Recombine: high * 2^128 + low
(high as f64) * 2_f64.powi(128) + (low as f64)
} else {
// self == i256::MIN → exactly 2^255
2_f64.powi(255)
};
// Reapply the sign bit
Some(if *self < i256::ZERO { -mag } else { mag })
}
// ... other methods unchanged ...
}
Metadata
Metadata
Assignees
Labels
No labels