1
2 /* @(#)s_frexp.c 5.1 93/09/24 */
3 /*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 */
13
14 /*
15 FUNCTION
16 <<frexp>>, <<frexpf>>---split floating-point number
17 INDEX
18 frexp
19 INDEX
20 frexpf
21
22 SYNOPSIS
23 #include <math.h>
24 double frexp(double <[val]>, int *<[exp]>);
25 float frexpf(float <[val]>, int *<[exp]>);
26
27 DESCRIPTION
28 All nonzero, normal numbers can be described as <[m]> * 2**<[p]>.
29 <<frexp>> represents the double <[val]> as a mantissa <[m]>
30 and a power of two <[p]>. The resulting mantissa will always
31 be greater than or equal to <<0.5>>, and less than <<1.0>> (as
32 long as <[val]> is nonzero). The power of two will be stored
33 in <<*>><[exp]>.
34
35 @ifnottex
36 <[m]> and <[p]> are calculated so that
37 <[val]> is <[m]> times <<2>> to the power <[p]>.
38 @end ifnottex
39 @tex
40 <[m]> and <[p]> are calculated so that
41 $ val = m \times 2^p $.
42 @end tex
43
44 <<frexpf>> is identical, other than taking and returning
45 floats rather than doubles.
46
47 RETURNS
48 <<frexp>> returns the mantissa <[m]>. If <[val]> is <<0>>, infinity,
49 or Nan, <<frexp>> will set <<*>><[exp]> to <<0>> and return <[val]>.
50
51 PORTABILITY
52 <<frexp>> is ANSI.
53 <<frexpf>> is an extension.
54
55
56 */
57
58 /*
59 * for non-zero x
60 * x = frexp(arg,&exp);
61 * return a double fp quantity x such that 0.5 <= |x| <1.0
62 * and the corresponding binary exponent "exp". That is
63 * arg = x*2^exp.
64 * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
65 * with *exp=0.
66 */
67
68 #include "fdlibm.h"
69
70 #ifdef _NEED_FLOAT64
71
72 static const double two54 =
73 _F_64(1.80143985094819840000e+16); /* 0x43500000, 0x00000000 */
74
75 __float64
frexp64(__float64 x,int * eptr)76 frexp64(__float64 x, int *eptr)
77 {
78 __int32_t hx, ix, lx;
79 EXTRACT_WORDS(hx, lx, x);
80 ix = 0x7fffffff & hx;
81 *eptr = 0;
82 if (ix >= 0x7ff00000 || ((ix | lx) == 0))
83 return x + x; /* 0,inf,nan */
84 if (ix < 0x00100000) { /* subnormal */
85 x *= two54;
86 GET_HIGH_WORD(hx, x);
87 ix = hx & 0x7fffffff;
88 *eptr = -54;
89 }
90 *eptr += (ix >> 20) - 1022;
91 hx = (hx & 0x800fffff) | 0x3fe00000;
92 SET_HIGH_WORD(x, hx);
93 return x;
94 }
95
96 _MATH_ALIAS_d_dI(frexp)
97
98 #endif /* _NEED_FLOAT64 */
99