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