miguelcorderopamphile opened a new issue, #11316: URL: https://github.com/apache/arrow-rs/issues/11316
### Describe the bug `i256` only implements `ToPrimitive::to_f64`, so `ToPrimitive::to_f32` falls back to the default `to_f64() as f32`. When the exact value is within half an `f64` ULP of an `f32` midpoint, the intermediate rounding moves it across the midpoint and the result differs from a correctly rounded `f32`. Verified on `main` (Rust): | value | correctly rounded (`i128 as f32`) | `i256::to_f32()` | | --- | --- | --- | | `2^53 + 2^29 + 1` | `0x5a000001` | `0x5a000000` | | `-(2^53 + 2^29 + 1)` | `0xda000001` | `0xda000000` | | `2^54 + 2^30 + 1` | `0x5a800001` | `0x5a800000` | For `v = 9007199791611905`, the expected `f32` is `9007200328482816.0` and `to_f32()` returns `9007199254740992.0`. ### To Reproduce ```rust use arrow_buffer::i256; use num_traits::ToPrimitive; let v: i128 = (1 << 53) + (1 << 29) + 1; let value = i256::from_i128(v); assert_eq!(value.to_f32().unwrap().to_bits(), (v as f32).to_bits()); // fails ``` ### Expected behavior For values in the `i128` range, `i256::to_f32` should match `i128 as f32` (correctly rounded), the same expectation that `to_f64` now satisfies after #11315. ### Additional context Found while validating #11315. Similar values exist across f32 exponents (the double-rounding window is around 2^-29, so they are rare in practice). There are no in-tree callers of `i256::to_f32`; `Decimal256 -> Float32` goes through `to_f64` plus scaling. Low impact, but a correctness gap in the public conversion. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
