base/math/logb.c

Go to the documentation of this file.
00001 #if defined(__ppc__) 00002 /******************************************************************************* 00003 * * 00004 * File logb.c, * 00005 * Functions logb. * 00006 * Implementation of logb for the PowerPC. * 00007 * * 00008 * Copyright © 1991 Apple Computer, Inc. All rights reserved. * 00009 * * 00010 * Written by Ali Sazegari, started on June 1991, * 00011 * * 00012 * August 26 1991: removed CFront Version 1.1d17 warnings. * 00013 * August 27 1991: no errors reported by the test suite. * 00014 * November 11 1991: changed CLASSEXTENDED to the macro CLASSIFY and * 00015 * + or - infinity to constants. * 00016 * November 18 1991: changed the macro CLASSIFY to CLASSEXTENDEDint to * 00017 * improve performance. * 00018 * February 07 1992: changed bit operations to macros ( object size is * 00019 * unchanged ). * 00020 * September24 1992: took the "#include support.h" out. * 00021 * December 03 1992: first rs/6000 port. * 00022 * August 30 1992: set the divide by zero for the zero argument case. * 00023 * October 05 1993: corrected the environment. * 00024 * October 17 1994: replaced all environmental functions with __setflm. * 00025 * May 28 1997: made speed improvements. * 00026 * April 30 2001: forst mac os x port using gcc. * 00027 * * 00028 ******************************************************************************** 00029 * The C math library offers a similar function called "frexp". It is * 00030 * different in details from logb, but similar in spirit. This current * 00031 * implementation of logb follows the recommendation in IEEE Standard 854 * 00032 * which is different in its handling of denormalized numbers from the IEEE * 00033 * Standard 754. * 00034 *******************************************************************************/ 00035 00036 typedef union 00037 { 00038 struct { 00039 #if defined(__BIG_ENDIAN__) 00040 unsigned long int hi; 00041 unsigned long int lo; 00042 #else 00043 unsigned long int lo; 00044 unsigned long int hi; 00045 #endif 00046 } words; 00047 double dbl; 00048 } DblInHex; 00049 00050 static const double twoTo52 = 4.50359962737049600e15; // 0x1p52 00051 static const double klTod = 4503601774854144.0; // 0x1.000008p52 00052 static const unsigned long int signMask = 0x80000000ul; 00053 static const DblInHex minusInf = {{ 0xFFF00000, 0x00000000 }}; 00054 00055 00056 /******************************************************************************* 00057 ******************************************************************************** 00058 * L O G B * 00059 ******************************************************************************** 00060 *******************************************************************************/ 00061 00062 double logb ( double x ) 00063 { 00064 DblInHex xInHex; 00065 long int shiftedExp; 00066 00067 xInHex.dbl = x; 00068 shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20; 00069 00070 if ( shiftedExp == 2047 ) 00071 { // NaN or INF 00072 if ( ( ( xInHex.words.hi & signMask ) == 0 ) || ( x != x ) ) 00073 return x; // NaN or +INF return x 00074 else 00075 return -x; // -INF returns +INF 00076 } 00077 00078 if ( shiftedExp != 0 ) // normal number 00079 shiftedExp -= 1023; // unbias exponent 00080 00081 else if ( x == 0.0 ) 00082 { // zero 00083 xInHex.words.hi = 0x0UL; // return -infinity 00084 return ( minusInf.dbl ); 00085 } 00086 00087 else 00088 { // subnormal number 00089 xInHex.dbl *= twoTo52; // scale up 00090 shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20; 00091 shiftedExp -= 1075; // unbias exponent 00092 } 00093 00094 if ( shiftedExp == 0 ) // zero result 00095 return ( 0.0 ); 00096 00097 else 00098 { // nonzero result 00099 xInHex.dbl = klTod; 00100 xInHex.words.lo += shiftedExp; 00101 return ( xInHex.dbl - klTod ); 00102 } 00103 } 00104 #endif /* __ppc__ */

Generated on Thu Nov 20 11:49:51 2008 for RTAI API by doxygen 1.3.8