-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Description
This ticket tracks potentially improving performance of i256 --> f64 conversion via manually twiddling bits from @scovich
Bit twiddling that I think would work:
- Define
i256::leading_zeros()
that follows the semantics of all the otherleading_zeros
for integral typesimpl i256 { pub fn leading_zeros(&self) -> u32 { match self.high { 0 => 128 + self.low.leading_zeros(), _ => self.high.leading_zeros(), } } }
- Define a notion of "redundant leading sign bits" in terms of leading zeros:
fn redundant_leading_sign_bits_i256(n: i256) -> u32 { let mask = n >> 255; // all ones or all zeros (n ^ mask).leading_zeros() - 1; // we only need one sign bit }
- Shift out all redundant leading sign bits when converting to f64:
fn i256_to_f64(n: i256) -> f64 { let k = redundant_leading_sign_bits_i256(n); let n = n << k; // left-justify (no redundant sign bits) let n = (n.high >> 64) as i64; // throw away the lower 192 bits (n as f64) * f64::powi(2.0, 192-k) // convert to f64 and scale it }
The above should work for both positive and negative values
Originally posted by @scovich in #7986 (comment)
Metadata
Metadata
Assignees
Labels
No labels