Skip to content

Latest commit

 

History

History
73 lines (65 loc) · 1.86 KB

s_scalbn.c

File metadata and controls

73 lines (65 loc) · 1.86 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
Nov 4, 2017
Nov 4, 2017
13
14
* scalbln(double x, long n)
* scalbln(x,n) returns x * 2**n computed by exponent
15
16
17
18
19
20
* manipulation rather than by actually performing an
* exponentiation or a multiplication.
*/
#include "math_libm.h"
#include "math_private.h"
Nov 4, 2017
Nov 4, 2017
21
#include <limits.h>
Nov 18, 2018
Nov 18, 2018
23
24
25
26
#ifdef __WATCOMC__ /* Watcom defines huge=__huge */
#undef huge
#endif
Nov 4, 2017
Nov 4, 2017
27
28
29
30
31
static const double
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
huge = 1.0e+300,
tiny = 1.0e-300;
Nov 4, 2017
Nov 4, 2017
33
double scalbln(double x, long n)
Nov 4, 2017
Nov 4, 2017
35
36
37
38
39
40
41
42
43
44
45
46
47
int32_t k, hx, lx;
EXTRACT_WORDS(hx, lx, x);
k = (hx & 0x7ff00000) >> 20; /* extract exponent */
if (k == 0) { /* 0 or subnormal x */
if ((lx | (hx & 0x7fffffff)) == 0)
return x; /* +-0 */
x *= two54;
GET_HIGH_WORD(hx, x);
k = ((hx & 0x7ff00000) >> 20) - 54;
}
if (k == 0x7ff)
return x + x; /* NaN or Inf */
Jan 30, 2020
Jan 30, 2020
48
k = (int32_t)(k + n);
Nov 4, 2017
Nov 4, 2017
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
if (k > 0x7fe)
return huge * copysign(huge, x); /* overflow */
if (n < -50000)
return tiny * copysign(tiny, x); /* underflow */
if (k > 0) { /* normal result */
SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
return x;
}
if (k <= -54) {
if (n > 50000) /* in case integer overflow in n+k */
return huge * copysign(huge, x); /* overflow */
return tiny * copysign(tiny, x); /* underflow */
}
k += 54; /* subnormal result */
SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
return x * twom54;
Nov 4, 2017
Nov 4, 2017
66
libm_hidden_def(scalbln)
Nov 5, 2017
Nov 5, 2017
68
Nov 4, 2017
Nov 4, 2017
69
70
71
72
double scalbn(double x, int n)
{
return scalbln(x, n);
}
73
libm_hidden_def(scalbn)