genericopenlibs/cstdlib/LMATH/FDLIBM.H
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* FDLIBM.H
       
     2  * 
       
     3  * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies).
       
     4  * All rights reserved.
       
     5  */
       
     6 
       
     7 
       
     8 /* @(#)fdlibm.h 5.1 93/09/24 */
       
     9 /*
       
    10  * ====================================================
       
    11  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       
    12  *
       
    13  * Developed at SunPro, a Sun Microsystems, Inc. business.
       
    14  * Permission to use, copy, modify, and distribute this
       
    15  * software is freely granted, provided that this notice 
       
    16  * is preserved.
       
    17  * ====================================================
       
    18  */
       
    19 
       
    20 #ifdef __cplusplus
       
    21 extern "C" {
       
    22 #endif
       
    23 
       
    24 /**
       
    25 SYMBIAN adaptations 
       
    26 @internalComponent
       
    27 */
       
    28 #define huge	fhuge
       
    29 #define tiny	ftiny
       
    30 /**
       
    31 @internalComponent
       
    32 */
       
    33 typedef unsigned long	__uint32_t;
       
    34 typedef long			__int32_t;
       
    35 
       
    36 #ifdef __VC32__
       
    37 /* warning C4056: overflow in floating-point constant arithmetic 
       
    38  * Caused by negative floating point constants, it seems!
       
    39  * For example, static double foo = -1.0;
       
    40  */
       
    41 #pragma warning( disable: 4056 )
       
    42 #endif
       
    43 #ifdef __ARMCC__
       
    44 /* Warning:  #222-D: floating-point operation result is out of range
       
    45  * The compiler detects constant math that overflows, we want overflow though!
       
    46  */
       
    47 #pragma diag_suppress 222
       
    48 #endif
       
    49 
       
    50 #include <math.h>
       
    51 /**
       
    52 @internalComponent
       
    53 */
       
    54 #define	HUGE	((float)3.40282346638528860e+38)
       
    55 
       
    56 /** 
       
    57 set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
       
    58 (one may replace the following line by "#include <values.h>")
       
    59 @internalComponent
       
    60 */
       
    61 #define X_TLOSS		1.41484755040568800000e+16 
       
    62 
       
    63 /**
       
    64 ieee style elementary functions - ESTLIB is exporting
       
    65 these functions directly, so we simply map the names across
       
    66 @internalComponent
       
    67 */
       
    68 #define __ieee754_cosh	cosh			
       
    69 #define __ieee754_sinh	sinh			
       
    70 #define __ieee754_tanh	tanh	
       
    71 #define __ieee754_exp	exp			
       
    72 
       
    73 /* The original code used statements like
       
    74 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
       
    75 	ix0 = *(n0+(int*)&x);			* high word of x *
       
    76 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
       
    77    to dig two 32 bit words out of the 64 bit IEEE floating point
       
    78    value.  That is non-ANSI, and, moreover, the gcc instruction
       
    79    scheduler gets it wrong.  We instead use the following macros.
       
    80    Unlike the original code, we determine the endianness at compile
       
    81    time, not at run time; I don't see much benefit to selecting
       
    82    endianness at run time.  */
       
    83 
       
    84 #ifndef __IEEE_BIG_ENDIAN
       
    85 #ifndef __IEEE_LITTLE_ENDIAN
       
    86  #error Must define endianness
       
    87 #endif
       
    88 #endif
       
    89 
       
    90 /* A union which permits us to convert between a double and two 32 bit
       
    91    ints.  */
       
    92 
       
    93 #ifdef __IEEE_BIG_ENDIAN
       
    94 /**
       
    95 @internalComponent
       
    96 */
       
    97 typedef union 
       
    98 {
       
    99   double value;
       
   100   struct 
       
   101   {
       
   102     unsigned long msw;
       
   103     unsigned long lsw;
       
   104   } parts;
       
   105 } ieee_double_shape_type;
       
   106 
       
   107 #else
       
   108 
       
   109 #ifdef __IEEE_LITTLE_ENDIAN
       
   110 /**
       
   111 @internalComponent
       
   112 */
       
   113 typedef union 
       
   114 {
       
   115   double value;
       
   116   struct 
       
   117   {
       
   118     unsigned long lsw;
       
   119     unsigned long msw;
       
   120   } parts;
       
   121 } ieee_double_shape_type;
       
   122 
       
   123 #endif
       
   124 #endif
       
   125 
       
   126 /**
       
   127 Get two 32 bit ints from a double.  
       
   128 @internalComponent
       
   129 */
       
   130 #define EXTRACT_WORDS(ix0,ix1,d)				\
       
   131 {								\
       
   132   ieee_double_shape_type ew_u;					\
       
   133   ew_u.value = (d);						\
       
   134   (ix0) = ew_u.parts.msw;					\
       
   135   (ix1) = ew_u.parts.lsw;					\
       
   136 }
       
   137 
       
   138 /** 
       
   139 Get the more significant 32 bit int from a double.  
       
   140 @internalComponent
       
   141 */
       
   142 #define GET_HIGH_WORD(i,d)					\
       
   143 {								\
       
   144   ieee_double_shape_type gh_u;					\
       
   145   gh_u.value = (d);						\
       
   146   (i) = gh_u.parts.msw;						\
       
   147 }
       
   148 
       
   149 /**
       
   150 Get the less significant 32 bit int from a double.  
       
   151 @internalComponent
       
   152 */
       
   153 #define GET_LOW_WORD(i,d)					\
       
   154 {								\
       
   155   ieee_double_shape_type gl_u;					\
       
   156   gl_u.value = (d);						\
       
   157   (i) = gl_u.parts.lsw;						\
       
   158 }
       
   159 
       
   160 /**
       
   161 Set a double from two 32 bit ints.  
       
   162 @internalComponent
       
   163 */
       
   164 #define INSERT_WORDS(d,ix0,ix1)					\
       
   165 {								\
       
   166   ieee_double_shape_type iw_u;					\
       
   167   iw_u.parts.msw = (ix0);					\
       
   168   iw_u.parts.lsw = (ix1);					\
       
   169   (d) = iw_u.value;						\
       
   170 }
       
   171 
       
   172 /** 
       
   173 Set the more significant 32 bits of a double from an int.  
       
   174 @internalComponent
       
   175 */
       
   176 #define SET_HIGH_WORD(d,v)					\
       
   177 {								\
       
   178   ieee_double_shape_type sh_u;					\
       
   179   sh_u.value = (d);						\
       
   180   sh_u.parts.msw = (v);						\
       
   181   (d) = sh_u.value;						\
       
   182 }
       
   183 
       
   184 /** 
       
   185 Set the less significant 32 bits of a double from an int.  
       
   186 @internalComponent
       
   187 */
       
   188 #define SET_LOW_WORD(d,v)					\
       
   189 {								\
       
   190   ieee_double_shape_type sl_u;					\
       
   191   sl_u.value = (d);						\
       
   192   sl_u.parts.lsw = (v);						\
       
   193   (d) = sl_u.value;						\
       
   194 }
       
   195 
       
   196 /** 
       
   197 A union which permits us to convert between a float and a 32 bit
       
   198 int.  
       
   199 @internalComponent
       
   200 */
       
   201 typedef union
       
   202 {
       
   203   float value;
       
   204   unsigned long word;
       
   205 } ieee_float_shape_type;
       
   206 
       
   207 /**
       
   208 Get a 32 bit int from a float.  
       
   209 @internalComponent
       
   210 */
       
   211 #define GET_FLOAT_WORD(i,d)					\
       
   212 {								\
       
   213   ieee_float_shape_type gf_u;					\
       
   214   gf_u.value = (d);						\
       
   215   (i) = gf_u.word;						\
       
   216 }
       
   217 
       
   218 /** 
       
   219 Set a float from a 32 bit int.  
       
   220 @internalComponent
       
   221 */
       
   222 #define SET_FLOAT_WORD(d,i)					\
       
   223 {								\
       
   224   ieee_float_shape_type sf_u;					\
       
   225   sf_u.word = (i);						\
       
   226   (d) = sf_u.value;						\
       
   227 }
       
   228 
       
   229 /**
       
   230 Test a 32-bit value for being 0.
       
   231 (x==0)? 0: (some value with top bit set to 1)
       
   232 @internalComponent
       
   233 */
       
   234 
       
   235 #define CHECK_ZERO(x)	((x)|-(__int32_t)(x))
       
   236 
       
   237 #ifdef __cplusplus
       
   238 }
       
   239 #endif