1 /**************************************************************** 2 * 3 * The author of this software is David M. Gay. 4 * 5 * Copyright (c) 1991 by AT&T. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose without fee is hereby granted, provided that this entire notice 9 * is included in all copies of any software which is or includes a copy 10 * or modification of this software and in all copies of the supporting 11 * documentation for such software. 12 * 13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY 15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 17 * 18 ***************************************************************/ 19 20 /* Please send bug reports to 21 David M. Gay 22 AT&T Bell Laboratories, Room 2C-463 23 600 Mountain Avenue 24 Murray Hill, NJ 07974-2070 25 U.S.A. 26 dmg@research.att.com or research!dmg 27 */ 28 29 /* This header file is a modification of mprec.h that only contains floating 30 point union code. */ 31 32 #include <math.h> 33 #include <float.h> 34 #include <errno.h> 35 36 #ifdef __IEEE_LITTLE_ENDIAN 37 #define IEEE_8087 38 #endif 39 40 #ifdef __IEEE_BIG_ENDIAN 41 #define IEEE_MC68k 42 #endif 43 44 #ifdef __Z8000__ 45 #define Just_16 46 #endif 47 48 #ifdef Unsigned_Shifts 49 #define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000; 50 #else 51 #define Sign_Extend(a,b) /*no-op*/ 52 #endif 53 54 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 55 Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. 56 #endif 57 58 #ifdef _WANT_IO_LONG_DOUBLE 59 /* If we are going to examine or modify specific bits in a long double using 60 the lword0 or lwordx macros, then we must wrap the long double inside 61 a union. This is necessary to avoid undefined behavior according to 62 the ANSI C spec. */ 63 64 #ifdef IEEE_8087 65 #if LDBL_MANT_DIG == 24 66 struct ldieee 67 { 68 __uint32_t manh:23; 69 __uint32_t exp:8; 70 __uint32_t sign:1; 71 } __packed; 72 #elif LDBL_MANT_DIG == 53 73 struct ldieee 74 { 75 __uint32_t manl:20; 76 __uint32_t manh:32; 77 __uint32_t exp:11; 78 __uint32_t sign:1; 79 } __packed; 80 #elif LDBL_MANT_DIG == 64 81 struct ldieee 82 { 83 __uint32_t manl:32; 84 __uint32_t manh:32; 85 __uint32_t exp:15; 86 __uint32_t sign:1; 87 } __packed; 88 #elif LDBL_MANT_DIG > 64 89 struct ldieee 90 { 91 __uint32_t manl3:16; 92 __uint32_t manl2:32; 93 __uint32_t manl:32; 94 __uint32_t manh:32; 95 __uint32_t exp:15; 96 __uint32_t sign:1; 97 } __packed; 98 #endif /* LDBL_MANT_DIG */ 99 #else /* !IEEE_8087 */ 100 #if LDBL_MANT_DIG == 24 101 struct ldieee 102 { 103 __uint32_t sign:1; 104 __uint32_t exp:8; 105 __uint32_t manh:23; 106 } __packed; 107 #elif LDBL_MANT_DIG == 53 108 struct ldieee 109 { 110 __uint32_t sign:1; 111 __uint32_t exp:11; 112 __uint32_t manh:32; 113 __uint32_t manl:20; 114 } __packed; 115 #elif LDBL_MANT_DIG == 64 116 struct ldieee 117 { 118 __uint32_t sign:1; 119 __uint32_t exp:15; 120 __uint32_t manh:32; 121 __uint32_t manl:32; 122 } __packed; 123 #elif LDBL_MANT_DIG > 64 124 struct ldieee 125 { 126 __uint32_t sign:1; 127 __uint32_t exp:15; 128 __uint32_t manh:32; 129 __uint32_t manl:32; 130 __uint32_t manl2:32; 131 __uint32_t manl3:16; 132 } __packed; 133 #endif /* LDBL_MANT_DIG */ 134 #endif /* !IEEE_8087 */ 135 #endif /* _WANT_IO_LONG_DOUBLE */ 136 137 /* If we are going to examine or modify specific bits in a double using 138 the word0 and/or word1 macros, then we must wrap the double inside 139 a union. This is necessary to avoid undefined behavior according to 140 the ANSI C spec. */ 141 union double_union 142 { 143 double d; 144 __uint32_t i[2]; 145 }; 146 147 #ifdef IEEE_8087 148 #define word0(x) (x.i[1]) 149 #define word1(x) (x.i[0]) 150 #else 151 #define word0(x) (x.i[0]) 152 #define word1(x) (x.i[1]) 153 #endif 154 155 /* #define P DBL_MANT_DIG */ 156 /* Ten_pmax = floor(P*log(2)/log(5)) */ 157 /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ 158 /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ 159 /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ 160 161 #if defined(IEEE_8087) + defined(IEEE_MC68k) 162 #if defined (_DOUBLE_IS_32BITS) 163 #define Exp_shift 23 164 #define Exp_shift1 23 165 #define Exp_msk1 ((__uint32_t)0x00800000L) 166 #define Exp_msk11 ((__uint32_t)0x00800000L) 167 #define Exp_mask ((__uint32_t)0x7f800000L) 168 #define P 24 169 #define Bias ((__uint32_t)127) 170 #define IEEE_Arith 171 #define Emin (-126) 172 #define Exp_1 ((__uint32_t)0x3f800000L) 173 #define Exp_11 ((__uint32_t)0x3f800000L) 174 #define Ebits 8 175 #define Frac_mask ((__uint32_t)0x007fffffL) 176 #define Frac_mask1 ((__uint32_t)0x007fffffL) 177 #define Ten_pmax 10 178 #define Sign_bit ((__uint32_t)0x80000000L) 179 #define Ten_pmax 10 180 #define Bletch 2 181 #define Bndry_mask ((__uint32_t)0x007fffffL) 182 #define Bndry_mask1 ((__uint32_t)0x007fffffL) 183 #define LSB 1 184 #define Sign_bit ((__uint32_t)0x80000000L) 185 #define Log2P 1 186 #define Tiny0 0 187 #define Tiny1 1 188 #define Quick_max 5 189 #define Int_max 6 190 #define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L)) 191 #undef word0 192 #undef word1 193 194 #define word0(x) (x.i[0]) 195 #define word1(x) 0 196 #else 197 198 #define Exp_shift 20 199 #define Exp_shift1 20 200 #define Exp_msk1 ((__uint32_t)0x100000L) 201 #define Exp_msk11 ((__uint32_t)0x100000L) 202 #define Exp_mask ((__uint32_t)0x7ff00000L) 203 #define P 53 204 #define Bias ((__uint32_t) 1023) 205 #define IEEE_Arith 206 #define Emin (-1022) 207 #define Exp_1 ((__uint32_t)0x3ff00000L) 208 #define Exp_11 ((__uint32_t)0x3ff00000L) 209 #define Ebits 11 210 #define Frac_mask ((__uint32_t)0xfffffL) 211 #define Frac_mask1 ((__uint32_t)0xfffffL) 212 #define Ten_pmax 22 213 #define Bletch 0x10 214 #define Bndry_mask ((__uint32_t)0xfffffL) 215 #define Bndry_mask1 ((__uint32_t)0xfffffL) 216 #define LSB 1 217 #define Sign_bit ((__uint32_t)0x80000000L) 218 #define Log2P 1 219 #define Tiny0 0 220 #define Tiny1 1 221 #define Quick_max 14 222 #define Int_max 14 223 #define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */ 224 #endif 225 226 #else 227 #undef Sudden_Underflow 228 #define Sudden_Underflow 229 #ifdef IBM 230 #define Exp_shift 24 231 #define Exp_shift1 24 232 #define Exp_msk1 ((__uint32_t)0x1000000L) 233 #define Exp_msk11 ((__uint32_t)0x1000000L) 234 #define Exp_mask ((__uint32_t)0x7f000000L) 235 #define P 14 236 #define Bias ((__uint32_T) 65) 237 #define Exp_1 ((__uint32_t)0x41000000L) 238 #define Exp_11 ((__uint32_t)0x41000000L) 239 #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ 240 #define Frac_mask ((__uint32_t)0xffffffL) 241 #define Frac_mask1 ((__uint32_t)0xffffffL) 242 #define Bletch 4 243 #define Ten_pmax 22 244 #define Bndry_mask ((__uint32_t)0xefffffL) 245 #define Bndry_mask1 ((__uint32_t)0xffffffL) 246 #define LSB 1 247 #define Sign_bit ((__uint32_t)0x80000000L) 248 #define Log2P 4 249 #define Tiny0 ((__uint32_t)0x100000L) 250 #define Tiny1 0 251 #define Quick_max 14 252 #define Int_max 15 253 #else /* VAX */ 254 #define Exp_shift 23 255 #define Exp_shift1 7 256 #define Exp_msk1 0x80 257 #define Exp_msk11 ((__uint32_t)0x800000L) 258 #define Exp_mask ((__uint32_t)0x7f80L) 259 #define P 56 260 #define Bias ((__uint32_t) 129) 261 #define Exp_1 ((__uint32_t)0x40800000L) 262 #define Exp_11 ((__uint32_t)0x4080L) 263 #define Ebits 8 264 #define Frac_mask ((__uint32_t)0x7fffffL) 265 #define Frac_mask1 ((__uint32_t)0xffff007fL) 266 #define Ten_pmax 24 267 #define Bletch 2 268 #define Bndry_mask ((__uint32_t)0xffff007fL) 269 #define Bndry_mask1 ((__uint32_t)0xffff007fL) 270 #define LSB ((__uint32_t)0x10000L) 271 #define Sign_bit ((__uint32_t)0x8000L) 272 #define Log2P 1 273 #define Tiny0 0x80 274 #define Tiny1 0 275 #define Quick_max 15 276 #define Int_max 15 277 #endif 278 #endif 279 280 281