const FRACTION_MASK: u64 = (1_u64 << 52) - 1;
const SIGN_BIT: u64 = 1_u64 << 63;
const INFINITY_BITS: u64 = 0x7ff0_0000_0000_0000;
pub(super) fn multiply(a: f64, b: f64, c: f64) -> f64 {
let bits = [a.to_bits(), b.to_bits(), c.to_bits()];
if bits.iter().any(|value| value & !SIGN_BIT == 0) {
return 0.0;
}
let negative = (bits[0] ^ bits[1] ^ bits[2]) & SIGN_BIT != 0;
let (first, first_exponent) = decompose(bits[0]);
let (second, second_exponent) = decompose(bits[1]);
let (third, third_exponent) = decompose(bits[2]);
let magnitude = integer_product(first, second, third);
let exponent = first_exponent + second_exponent + third_exponent;
f64::from_bits(round(magnitude, exponent) | if negative { SIGN_BIT } else { 0 })
}
fn decompose(bits: u64) -> (u64, i32) {
let field = ((bits >> 52) & 0x7ff) as i32;
let fraction = bits & FRACTION_MASK;
if field == 0 {
(fraction, -1074)
} else {
(fraction | (1_u64 << 52), field - 1075)
}
}
#[expect(
clippy::cast_possible_truncation,
reason = "low-limb casts deliberately retain the bottom 64 bits; high limbs are bounded"
)]
fn integer_product(a: u64, b: u64, c: u64) -> [u64; 3] {
let pair = u128::from(a) * u128::from(b);
let low = u128::from(pair as u64) * u128::from(c);
let high = (pair >> 64) * u128::from(c) + (low >> 64);
[low as u64, high as u64, (high >> 64) as u64]
}
#[expect(
clippy::cast_sign_loss,
reason = "the retained shift and finite biased exponent are nonnegative by construction"
)]
fn round(words: [u64; 3], exponent: i32) -> u64 {
let top = highest_bit(&words) + exponent;
if top > 1023 {
return INFINITY_BITS;
}
let unit_exponent = (top - 52).max(-1074);
let shift = (unit_exponent - exponent) as u32;
let mut retained = shifted_low(&words, shift);
if shift != 0 {
let guard = bit(&words, shift - 1);
let sticky = any_below(&words, shift - 1);
if guard && (sticky || retained & 1 != 0) {
retained += 1;
}
}
if top < -1022 {
return retained;
}
let mut rounded_top = top;
if retained == 1_u64 << 53 {
retained >>= 1;
rounded_top += 1;
}
if rounded_top > 1023 {
INFINITY_BITS
} else {
((rounded_top + 1023) as u64) << 52 | (retained & FRACTION_MASK)
}
}
#[expect(
clippy::cast_possible_wrap,
reason = "leading-zero counts are at most 64"
)]
fn highest_bit(words: &[u64; 3]) -> i32 {
if words[2] != 0 {
191 - words[2].leading_zeros() as i32
} else if words[1] != 0 {
127 - words[1].leading_zeros() as i32
} else {
63 - words[0].leading_zeros() as i32
}
}
fn shifted_low(words: &[u64; 3], shift: u32) -> u64 {
let limb = (shift / 64) as usize;
if limb >= words.len() {
return 0;
}
let offset = shift % 64;
let low = words[limb] >> offset;
if offset == 0 || limb + 1 == words.len() {
low
} else {
low | words[limb + 1] << (64 - offset)
}
}
fn bit(words: &[u64; 3], position: u32) -> bool {
let limb = (position / 64) as usize;
limb < words.len() && words[limb] & (1_u64 << (position % 64)) != 0
}
fn any_below(words: &[u64; 3], position: u32) -> bool {
let complete = (position / 64) as usize;
let remainder = position % 64;
if complete >= words.len() {
return words.iter().any(|value| *value != 0);
}
words[..complete].iter().any(|value| *value != 0)
|| (remainder != 0 && words[complete] & ((1_u64 << remainder) - 1) != 0)
}