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