The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 1 | /* |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 2 | * Copyright (c) 2005-2020 Rich Felker, et al. |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 3 | * |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 4 | * SPDX-License-Identifier: MIT |
| 5 | * |
| 6 | * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT |
| 7 | * for all contributors to musl. |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 8 | */ |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 9 | #include <float.h> |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 10 | #include <math.h> |
| 11 | #include <stdint.h> |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 12 | |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 13 | double scalbn(double x, int n) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 14 | { |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 15 | union {double f; uint64_t i;} u; |
| 16 | double_t y = x; |
| 17 | |
| 18 | if (n > 1023) { |
| 19 | y *= 0x1p1023; |
| 20 | n -= 1023; |
| 21 | if (n > 1023) { |
| 22 | y *= 0x1p1023; |
| 23 | n -= 1023; |
| 24 | if (n > 1023) |
| 25 | n = 1023; |
| 26 | } |
| 27 | } else if (n < -1022) { |
| 28 | /* make sure final n < -53 to avoid double |
| 29 | rounding in the subnormal range */ |
| 30 | y *= 0x1p-1022 * 0x1p53; |
| 31 | n += 1022 - 53; |
| 32 | if (n < -1022) { |
| 33 | y *= 0x1p-1022 * 0x1p53; |
| 34 | n += 1022 - 53; |
| 35 | if (n < -1022) |
| 36 | n = -1022; |
| 37 | } |
Elliott Hughes | 8da8ca4 | 2018-05-08 13:35:33 -0700 | [diff] [blame] | 38 | } |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 39 | u.i = (uint64_t)(0x3ff+n)<<52; |
| 40 | x = y * u.f; |
| 41 | return x; |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 42 | } |
| 43 | |
Elliott Hughes | 99ef447 | 2022-01-12 17:51:20 -0800 | [diff] [blame] | 44 | #if (LDBL_MANT_DIG == 53) && !defined(scalbn) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 45 | __weak_reference(scalbn, ldexpl); |
| 46 | __weak_reference(scalbn, scalbnl); |
| 47 | #endif |