summaryrefslogtreecommitdiffstats
path: root/vendor/compiler_builtins/libm/src/math/scalbn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/compiler_builtins/libm/src/math/scalbn.rs')
-rw-r--r--vendor/compiler_builtins/libm/src/math/scalbn.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/vendor/compiler_builtins/libm/src/math/scalbn.rs b/vendor/compiler_builtins/libm/src/math/scalbn.rs
new file mode 100644
index 000000000..00c455a10
--- /dev/null
+++ b/vendor/compiler_builtins/libm/src/math/scalbn.rs
@@ -0,0 +1,33 @@
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
+pub fn scalbn(x: f64, mut n: i32) -> f64 {
+ let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023
+ let x1p53 = f64::from_bits(0x4340000000000000); // 0x1p53 === 2 ^ 53
+ let x1p_1022 = f64::from_bits(0x0010000000000000); // 0x1p-1022 === 2 ^ (-1022)
+
+ let mut y = x;
+
+ if n > 1023 {
+ y *= x1p1023;
+ n -= 1023;
+ if n > 1023 {
+ y *= x1p1023;
+ n -= 1023;
+ if n > 1023 {
+ n = 1023;
+ }
+ }
+ } else if n < -1022 {
+ /* make sure final n < -53 to avoid double
+ rounding in the subnormal range */
+ y *= x1p_1022 * x1p53;
+ n += 1022 - 53;
+ if n < -1022 {
+ y *= x1p_1022 * x1p53;
+ n += 1022 - 53;
+ if n < -1022 {
+ n = -1022;
+ }
+ }
+ }
+ y * f64::from_bits(((0x3ff + n) as u64) << 52)
+}