]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/msun/src/s_scalbnl.c
pow,powf(3),__ieee754_rem_pio2(f): Avoid negative integer left shift UB
[FreeBSD/FreeBSD.git] / lib / msun / src / s_scalbnl.c
1 /*
2  * Copyright (c) 2005-2020 Rich Felker, et al.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
7  * for all contributors to musl.
8  */
9 #include <math.h>
10 #include <float.h>
11 #include "math_private.h"
12 #include "fpmath.h"
13 /*
14  * scalbnl (long double x, int n)
15  * scalbnl(x,n) returns x* 2**n  computed by  exponent
16  * manipulation rather than by actually performing an
17  * exponentiation or a multiplication.
18  */
19 #if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
20 long double scalbnl(long double x, int n)
21 {
22         union IEEEl2bits u;
23
24         if (n > 16383) {
25                 x *= 0x1p16383L;
26                 n -= 16383;
27                 if (n > 16383) {
28                         x *= 0x1p16383L;
29                         n -= 16383;
30                         if (n > 16383)
31                                 n = 16383;
32                 }
33         } else if (n < -16382) {
34                 x *= 0x1p-16382L * 0x1p113L;
35                 n += 16382 - 113;
36                 if (n < -16382) {
37                         x *= 0x1p-16382L * 0x1p113L;
38                         n += 16382 - 113;
39                         if (n < -16382)
40                                 n = -16382;
41                 }
42         }
43         u.e = 1.0;
44         u.xbits.expsign = 0x3fff + n;
45         return x * u.e;
46 }
47 __strong_reference(scalbnl, ldexpl);
48 #endif
49