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}
34