]> Git Repo - uclibc-ng.git/blob - libm/logb.c
Totally rework the math library, this time based on the MacOs X
[uclibc-ng.git] / libm / logb.c
1 #if defined(__ppc__)
2 /*******************************************************************************
3 *                                                                              *
4 *      File logb.c,                                                            *
5 *      Functions logb.                                                         *
6 *      Implementation of logb for the PowerPC.                                 *
7 *                                                                              *
8 *      Copyright © 1991 Apple Computer, Inc.  All rights reserved.             *
9 *                                                                              *
10 *      Written by Ali Sazegari, started on June 1991,                          *
11 *                                                                              *
12 *      August   26 1991: removed CFront Version 1.1d17 warnings.               *
13 *      August   27 1991: no errors reported by the test suite.                 *
14 *      November 11 1991: changed CLASSEXTENDED to the macro CLASSIFY and       *
15 *                        + or - infinity to constants.                         *
16 *      November 18 1991: changed the macro CLASSIFY to CLASSEXTENDEDint to     *
17 *                        improve performance.                                  *
18 *      February 07 1992: changed bit operations to macros (  object size is    *
19 *                        unchanged  ).                                         *
20 *      September24 1992: took the "#include support.h" out.                    *
21 *      December 03 1992: first rs/6000 port.                                   *
22 *      August   30 1992: set the divide by zero for the zero argument case.    *
23 *      October  05 1993: corrected the environment.                            *
24 *      October  17 1994: replaced all environmental functions with __setflm.   *
25 *      May      28 1997: made speed improvements.                              *
26 *      April    30 2001: forst mac os x port using gcc.                        *
27 *                                                                              *
28 ********************************************************************************
29 *     The C math library offers a similar function called "frexp".  It is      *
30 *     different in details from logb, but similar in spirit.  This current     *
31 *     implementation of logb follows the recommendation in IEEE Standard 854   *
32 *     which is different in its handling of denormalized numbers from the IEEE *
33 *     Standard 754.                                                            *
34 *******************************************************************************/
35
36 typedef union           
37       { 
38       struct {
39 #if defined(__BIG_ENDIAN__)
40         unsigned long int hi;
41         unsigned long int lo;
42 #else
43         unsigned long int lo;
44         unsigned long int hi;
45 #endif
46       } words;
47       double dbl;
48       } DblInHex;
49
50 static const double twoTo52 = 4.50359962737049600e15;              // 0x1p52
51 static const double klTod = 4503601774854144.0;                    // 0x1.000008p52
52 static const unsigned long int signMask = 0x80000000ul;
53 static const DblInHex minusInf  = {{ 0xFFF00000, 0x00000000 }};
54
55
56 /*******************************************************************************
57 ********************************************************************************
58 *                                    L  O  G  B                                *
59 ********************************************************************************
60 *******************************************************************************/
61
62 double logb (  double x  )
63       {
64       DblInHex xInHex;
65       long int shiftedExp;
66       
67       xInHex.dbl = x;
68       shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20;
69       
70       if ( shiftedExp == 2047 ) 
71             {                                            // NaN or INF
72             if ( ( ( xInHex.words.hi & signMask ) == 0 ) || ( x != x ) )
73                   return x;                              // NaN or +INF return x
74             else
75                   return -x;                             // -INF returns +INF
76             }
77       
78       if ( shiftedExp != 0 )                             // normal number
79             shiftedExp -= 1023;                          // unbias exponent
80       
81       else if ( x == 0.0 ) 
82             {                                            // zero
83             xInHex.words.hi = 0x0UL;                      // return -infinity
84             return (  minusInf.dbl  );
85             }
86       
87       else 
88             {                                            // subnormal number
89             xInHex.dbl *= twoTo52;                       // scale up
90             shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20;
91             shiftedExp -= 1075;                          // unbias exponent
92             }
93       
94       if ( shiftedExp == 0 )                             // zero result
95             return ( 0.0 );
96       
97       else 
98             {                                            // nonzero result
99             xInHex.dbl = klTod;
100             xInHex.words.lo += shiftedExp;
101             return ( xInHex.dbl - klTod );
102             }
103       }
104 #endif /* __ppc__ */
This page took 0.031802 seconds and 4 git commands to generate.