base/math/frexpldexp.c

Go to the documentation of this file.
00001 #if defined(__ppc__)
00002 /*******************************************************************************
00003 *                                                                              *
00004 *      File frexpldexp.c,                                                      *
00005 *      Functions frexp(x) and ldexp(x),                                        *
00006 *      Implementation of frexp and ldexp functions for the PowerPC.            *
00007 *                                                                              *
00008 *      Copyright © 1991 Apple Computer, Inc.  All rights reserved.             *
00009 *                                                                              *
00010 *      Written by Ali Sazegari, started on January 1991,                       *
00011 *                                                                              *
00012 *      W A R N I N G:  This routine expects a 64 bit double model.             *
00013 *                                                                              *
00014 *      December03 1992: first rs6000 implementation.                           *
00015 *      October 05 1993: added special cases for NaN and ° in frexp.            *
00016 *      May     27 1997: improved the performance of frexp by eliminating the   *
00017 *                       switch statement.                                      *
00018 *    June      13 2001: (ram) rewrote frexp to eliminate calls to scalb and    *
00019 *               logb.                                    *
00020 *                                                                              *
00021 *******************************************************************************/
00022 
00023 #include <limits.h>
00024 #include <math.h>
00025 
00026 static const double two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
00027 
00028 typedef union
00029       {
00030       struct {
00031 #if defined(__BIG_ENDIAN__)
00032         unsigned long int hi;
00033         unsigned long int lo;
00034 #else
00035         unsigned long int lo; 
00036         unsigned long int hi; 
00037 #endif
00038       } words;
00039       double dbl;
00040       } DblInHex;       
00041 
00042 double ldexp ( double value, int exp ) 
00043       {
00044       if ( exp > SHRT_MAX ) 
00045             exp = SHRT_MAX;
00046       else if ( exp < -SHRT_MAX ) 
00047             exp = -SHRT_MAX;
00048       return scalb ( value, exp  );
00049       }
00050 
00051 double frexp ( double value, int *eptr )
00052       {
00053       DblInHex argument;
00054       unsigned long int valueHead;
00055 
00056       argument.dbl = value;
00057       valueHead = argument.words.hi & 0x7fffffffUL; // valueHead <- |x|
00058 
00059       *eptr = 0;
00060     if ( valueHead >= 0x7ff00000 || ( valueHead | argument.words.lo ) == 0 )
00061         return value;       // 0, inf, or NaN
00062     
00063     if ( valueHead < 0x00100000 )
00064         {   // denorm
00065         argument.dbl = two54 * value;
00066         valueHead = argument.words.hi &0x7fffffff;
00067         *eptr = -54;
00068         }
00069     *eptr += ( valueHead >> 20 ) - 1022;
00070     argument.words.hi = ( argument.words.hi & 0x800fffff ) | 0x3fe00000;
00071     return argument.dbl;
00072     }
00073 #endif /* __ppc__ */

Generated on Tue Feb 2 17:46:05 2010 for RTAI API by  doxygen 1.4.7