libm/math/
scalbn.rs

1#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
2pub fn scalbn(x: f64, mut n: i32) -> f64 {
3    let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023
4    let x1p53 = f64::from_bits(0x4340000000000000); // 0x1p53 === 2 ^ 53
5    let x1p_1022 = f64::from_bits(0x0010000000000000); // 0x1p-1022 === 2 ^ (-1022)
6
7    let mut y = x;
8
9    if n > 1023 {
10        y *= x1p1023;
11        n -= 1023;
12        if n > 1023 {
13            y *= x1p1023;
14            n -= 1023;
15            if n > 1023 {
16                n = 1023;
17            }
18        }
19    } else if n < -1022 {
20        /* make sure final n < -53 to avoid double
21        rounding in the subnormal range */
22        y *= x1p_1022 * x1p53;
23        n += 1022 - 53;
24        if n < -1022 {
25            y *= x1p_1022 * x1p53;
26            n += 1022 - 53;
27            if n < -1022 {
28                n = -1022;
29            }
30        }
31    }
32    y * f64::from_bits(((0x3ff + n) as u64) << 52)
33}