gatesn opened a new issue, #11314:
URL: https://github.com/apache/arrow-rs/issues/11314

   ### Describe the bug
   
   This PR seems to suggest the desired behavior of `i256::to_f64` should match 
Rust's behavior: https://github.com/apache/arrow-rs/pull/7986, but my fuzzer 
wasn't so happy.
   
   I have checked a few of the existing decimal rounding and float conversion 
issues, but as far as I could tell none seem to quite cover this specific case 
which happens within i256::to_f64 itself. I may be wrong and feel free to close 
this as a duplicate!
   
   arrow-buffer = "=60.0.0"
   num-traits = "0.2"
   
   ```rust
   use arrow_buffer::i256;
   use num_traits::ToPrimitive;
   
   fn main() {
       // Neighboring floats here are 2048 apart. Halfway is lower + 1024.
       // The extra +1 makes this strictly closer to the upper float.
       let lower = 1_i128 << 63;
       let integer = lower + 1024 + 1;
       let value = i256::from_i128(integer);
       let actual = value.to_f64().unwrap();
       let expected = integer as f64;
   
       assert_eq!(integer, 9_223_372_036_854_776_833);
       println!("actual bits: {:016x}", actual.to_bits()); // 0x43e0000000000000
       assert_eq!(expected.to_bits(), 0x43e0000000000001); // nearest float
       assert_eq!(actual, expected);
   }
   ```
   
   I won't pretend to entirely understand what's going on here. Claude 
suggested this as a possible fix, although sadly it seems like it would come 
with a minor performance hit.
   
   ```diff
   -        let n = (n.high >> 64) as i64; // throw away the lower 192 bits
   +        // Retain whether any discarded bit is nonzero. Rounding the signed
   +        // prefix to odd preserves which side of a binary64 midpoint the
   +        // original integer lies on, for both positive and negative inputs.
   +        let sticky = n.low != 0 || (n.high as u64) != 0;
   +        let n = ((n.high >> 64) as i64) | i64::from(sticky);
   ```
   
   ### To Reproduce
   
   _No response_
   
   ### Expected behavior
   
   _No response_
   
   ### Additional context
   
   _No response_


-- 
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]

Reply via email to