Cygwin: //: fetch only one item per loop
[newlib-cygwin.git] / newlib / libm / mathfp / s_ldexp.c
blob6a844e0fef402d04cb0e41f1209c2320134e051b
2 /* @(#)z_ldexp.c 1.0 98/08/13 */
4 /*
5 FUNCTION
6 <<ldexp>>, <<ldexpf>>---load exponent
8 INDEX
9 ldexp
10 INDEX
11 ldexpf
13 SYNOPSIS
14 #include <math.h>
15 double ldexp(double <[val]>, int <[exp]>);
16 float ldexpf(float <[val]>, int <[exp]>);
18 DESCRIPTION
19 <<ldexp>> calculates the value
20 @ifnottex
21 <[val]> times 2 to the power <[exp]>.
22 @end ifnottex
23 @tex
24 $val\times 2^{exp}$.
25 @end tex
26 <<ldexpf>> is identical, save that it takes and returns <<float>>
27 rather than <<double>> values.
29 RETURNS
30 <<ldexp>> returns the calculated value.
32 Underflow and overflow both set <<errno>> to <<ERANGE>>.
33 On underflow, <<ldexp>> and <<ldexpf>> return 0.0.
34 On overflow, <<ldexp>> returns plus or minus <<HUGE_VAL>>.
36 PORTABILITY
37 <<ldexp>> is ANSI. <<ldexpf>> is an extension.
41 /******************************************************************
42 * ldexp
44 * Input:
45 * d - a floating point value
46 * e - an exponent value
48 * Output:
49 * A floating point value f such that f = d * 2 ^ e.
51 * Description:
52 * This function creates a floating point number f such that
53 * f = d * 2 ^ e.
55 *****************************************************************/
57 #include <float.h>
58 #include "fdlibm.h"
59 #include "zmath.h"
61 #ifndef _DOUBLE_IS_32BITS
63 #define DOUBLE_EXP_OFFS 1023
65 double
66 ldexp (double d,
67 int e)
69 int exp;
70 __uint32_t hd;
72 GET_HIGH_WORD (hd, d);
74 /* Check for special values and then scale d by e. */
75 switch (numtest (d))
77 case NAN:
78 errno = EDOM;
79 break;
81 case INF:
82 errno = ERANGE;
83 break;
85 case 0:
86 break;
88 default:
89 exp = (hd & 0x7ff00000) >> 20;
90 exp += e;
92 if (exp > DBL_MAX_EXP + DOUBLE_EXP_OFFS)
94 errno = ERANGE;
95 d = z_infinity.d;
97 else if (exp < DBL_MIN_EXP + DOUBLE_EXP_OFFS)
99 errno = ERANGE;
100 d = -z_infinity.d;
102 else
104 hd &= 0x800fffff;
105 hd |= exp << 20;
106 SET_HIGH_WORD (d, hd);
110 return (d);
113 #endif /* _DOUBLE_IS_32BITS */