POK
frexp.c
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Fri Jan 30 14:41:34 2009
15  */
16 
17 /* @(#)s_frexp.c 5.1 93/09/24 */
18 /*
19  * ====================================================
20  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
21  *
22  * Developed at SunPro, a Sun Microsystems, Inc. business.
23  * Permission to use, copy, modify, and distribute this
24  * software is freely granted, provided that this notice
25  * is preserved.
26  * ====================================================
27  */
28 
29 /*
30  * for non-zero x
31  * x = frexp(arg,&exp);
32  * return a double fp quantity x such that 0.5 <= |x| <1.0
33  * and the corresponding binary exponent "exp". That is
34  * arg = x*2^exp.
35  * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
36  * with *exp=0.
37  */
38 
39 #ifdef POK_NEEDS_LIBMATH
40 
41 #include <libm.h>
42 #include "math_private.h"
43 
44 static const double
45 two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
46 
47 double
48 frexp(double x, int *eptr)
49 {
50  int32_t hx, ix, lx;
51  EXTRACT_WORDS(hx,lx,x);
52  ix = 0x7fffffff&hx;
53  *eptr = 0;
54  if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
55  if (ix<0x00100000) { /* subnormal */
56  x *= two54;
57  GET_HIGH_WORD(hx,x);
58  ix = hx&0x7fffffff;
59  *eptr = -54;
60  }
61  *eptr += ((uint32_t)ix>>20)-1022;
62  hx = (hx&0x800fffff)|0x3fe00000;
63  SET_HIGH_WORD(x,hx);
64  return x;
65 }
66 
67 #endif