ldexp.c

Go to the documentation of this file.
00001 /*
00002 libc/ieee_float/ldexp.c
00003 
00004 Created:        Oct 14, 1993 by Philip Homburg <philip@cs.vu.nl>
00005 
00006 Implementation of ldexp that directly manipulates the exponent bits in an
00007 ieee float
00008 */
00009 
00010 #include <sys/types.h>
00011 #include <errno.h>
00012 #include <math.h>
00013 
00014 #include "ieee_float.h"
00015 
00016 double ldexp(value, exp)
00017 double value;
00018 int exp;
00019 {
00020         struct f64 *f64p;
00021         int oldexp, exp_bias;
00022         double factor;
00023 
00024         f64p= (struct f64 *)&value;
00025         exp_bias= 0;
00026 
00027         oldexp= F64_GET_EXP(f64p);
00028         if (oldexp == F64_EXP_MAX)
00029         {       /* Either infinity or Nan */
00030                 return value;
00031         }
00032         if (oldexp == 0)
00033         {
00034                 /* Either 0 or denormal */
00035                 if (F64_GET_MANT_LOW(f64p) == 0 &&
00036                         F64_GET_MANT_HIGH(f64p) == 0)
00037                 {
00038                         return value;
00039                 }
00040         }
00041 
00042         /* If exp is too large (> 2*F64_EXP_MAX) or too small
00043          * (< -2*F64_EXP_MAX) return HUGE_VAL or 0. This prevents overflows
00044          * in exp if exp is really weird
00045          */
00046         if (exp >= 2*F64_EXP_MAX)
00047         {
00048                 errno= ERANGE;
00049                 return HUGE_VAL;
00050         }
00051         if (exp <= -2*F64_EXP_MAX)
00052         {
00053                 errno= ERANGE;
00054                 return 0;
00055         }
00056         
00057         /* Normalize a denormal */
00058         if (oldexp == 0)
00059         {
00060                 /* Multiply by 2^64 */
00061                 factor= 65536.0;        /* 2^16 */
00062                 factor *= factor;       /* 2^32 */
00063                 factor *= factor;       /* 2^64 */
00064                 value *= factor;
00065                 exp= -64;
00066                 oldexp= F64_GET_EXP(f64p);
00067         }
00068 
00069         exp= oldexp + exp;
00070         if (exp >= F64_EXP_MAX)
00071         {       /* Overflow */
00072                 errno= ERANGE;
00073                 return HUGE_VAL;
00074         }
00075         if (exp > 0)
00076         {
00077                 /* Normal */
00078                 F64_SET_EXP(f64p, exp);
00079                 return value;
00080         }
00081         /* Denormal, or underflow. */
00082         exp += 64;
00083         F64_SET_EXP(f64p, exp);
00084         /* Divide by 2^64 */
00085         factor= 65536.0;        /* 2^16 */
00086         factor *= factor;       /* 2^32 */
00087         factor *= factor;       /* 2^64 */
00088         value /= factor;
00089         if (value == 0.0)
00090         {
00091                 /* Underflow */
00092                 errno= ERANGE;
00093         }
00094         return value;
00095 }
00096 
00097 /*
00098  * $PchId: ldexp.c,v 1.3 1996/02/22 21:01:39 philip Exp $
00099  */

Generated on Fri Apr 14 22:57:25 2006 for minix by  doxygen 1.4.6