Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gul_ieee.cpp

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  *  implementation of missing ieee functions for windows platforms
00022  */
00023 
00024 /*
00025  * ====================================================
00026  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00027  *
00028  * Developed at SunPro, a Sun Microsystems, Inc. business.
00029  * Permission to use, copy, modify, and distribute this
00030  * software is freely granted, provided that this notice 
00031  * is preserved.
00032  * ====================================================
00033  */
00034 
00035 #include "stdafx.h"
00036 
00037 #if defined(__MINGW32__) || (defined(_MSC_VER))
00038 
00039 #include "gul_types.h"
00040 
00041 using gul::int32;
00042 using gul::uint32;
00043 
00044 #define GET_HIGH_WORD(w,x) w = ((int32 *)&(x))[1]
00045 #define GET_LOW_WORD(w,x) w = ((int32 *)&(x))[0]
00046 #define EXTRACT_WORDS(h,l,x) h = ((int32 *)&(x))[1]; l = ((int32 *)&(x))[0];
00047 #define SET_HIGH_WORD(x,w) ((int32 *)&(x))[1] = w;
00048 
00049 /*
00050  * copysign(double x, double y)
00051  * copysign(x,y) returns a value with the magnitude of x and
00052  * with the sign bit of y.
00053  */
00054 
00055 GULAPI double copysign(double x, double y)
00056 {
00057   uint32 hx,hy;
00058   GET_HIGH_WORD(hx,x);
00059   GET_HIGH_WORD(hy,y);
00060   SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
00061   return x;
00062 }
00063 
00064 /* ilogb(double x)
00065  * return the binary exponent of non-zero x
00066  * ilogb(0) = 0x80000001
00067  * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
00068  */
00069 
00070 GULAPI int ilogb(double x)
00071 {
00072   int32 hx,lx,ix;
00073 
00074   GET_HIGH_WORD(hx,x);
00075   hx &= 0x7fffffff;
00076   if(hx<0x00100000)
00077   {
00078     GET_LOW_WORD(lx,x);
00079     if((hx|lx)==0) 
00080       return 0x80000001;      /* ilogb(0) = 0x80000001 */
00081     else                      /* subnormal x */
00082     {
00083       if(hx==0)
00084       {
00085         for (ix = -1043; lx>0; lx<<=1) ix -=1;
00086       } 
00087       else 
00088       {
00089         for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
00090       }
00091       return ix;
00092     }
00093   }
00094   else if (hx<0x7ff00000) 
00095     return (hx>>20)-1023;
00096 
00097   return 0x7fffffff;
00098 }
00099 
00100 /* 
00101  * scalbn (double x, int n)
00102  * scalbn(x,n) returns x* 2**n  computed by  exponent  
00103  * manipulation rather than by actually performing an 
00104  * exponentiation or a multiplication.
00105  */
00106 
00107 static const double
00108 two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
00109 twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
00110 hug   = 1.0e+300,
00111 tiny   = 1.0e-300;
00112 
00113 GULAPI double scalbn (double x, int n)
00114 {
00115   int32 k,hx,lx;
00116   EXTRACT_WORDS(hx,lx,x);
00117   k = (hx&0x7ff00000)>>20;            /* extract exponent */
00118   if (k==0)                           /* 0 or subnormal x */
00119   {                             
00120     if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
00121     x *= two54; 
00122     GET_HIGH_WORD(hx,x);
00123     k = ((hx&0x7ff00000)>>20) - 54; 
00124     if (n< -50000) return tiny*x;   /*underflow*/
00125   }
00126   if (k==0x7ff) return x+x;             /* NaN or Inf */
00127   k = k+n; 
00128   if (k >  0x7fe) return hug*copysign(hug,x); /* overflow  */
00129   if (k > 0)                            /* normal result */
00130   { 
00131     SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); 
00132     return x;
00133   }
00134   if (k <= -54)
00135     if (n > 50000)      /* in case integer overflow in n+k */
00136       return hug*copysign(hug,x);       /*overflow*/
00137     else 
00138       return tiny*copysign(tiny,x);     /*underflow*/
00139   k += 54;                              /* subnormal result */
00140   SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
00141   return x*twom54;
00142 }
00143 
00144 #endif
00145 

Generated on Mon Jan 21 04:17:32 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001