1 /* IEEE floating point support routines, for GDB, the GNU Debugger. 2 Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21 /* This is needed to pick up the NAN macro on some systems. */ 22 #define _GNU_SOURCE 23 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <math.h> 29 30 #ifdef HAVE_STRING_H 31 #include <string.h> 32 #endif 33 34 /* On some platforms, <float.h> provides DBL_QNAN. */ 35 #ifdef STDC_HEADERS 36 #include <float.h> 37 #endif 38 39 #include "ansidecl.h" 40 #include "libiberty.h" 41 #include "floatformat.h" 42 43 #ifndef INFINITY 44 #ifdef HUGE_VAL 45 #define INFINITY HUGE_VAL 46 #else 47 #define INFINITY (1.0 / 0.0) 48 #endif 49 #endif 50 51 #ifndef NAN 52 #ifdef DBL_QNAN 53 #define NAN DBL_QNAN 54 #else 55 #define NAN (0.0 / 0.0) 56 #endif 57 #endif 58 59 static int mant_bits_set (const struct floatformat *, const unsigned char *); 60 static unsigned long get_field (const unsigned char *, 61 enum floatformat_byteorders, 62 unsigned int, 63 unsigned int, 64 unsigned int); 65 static int floatformat_always_valid (const struct floatformat *fmt, 66 const void *from); 67 68 static int 69 floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED, 70 const void *from ATTRIBUTE_UNUSED) 71 { 72 return 1; 73 } 74 75 /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not 76 going to bother with trying to muck around with whether it is defined in 77 a system header, what we do if not, etc. */ 78 #define FLOATFORMAT_CHAR_BIT 8 79 80 /* floatformats for IEEE single and double, big and little endian. */ 81 const struct floatformat floatformat_ieee_single_big = 82 { 83 floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, 84 floatformat_intbit_no, 85 "floatformat_ieee_single_big", 86 floatformat_always_valid, 87 NULL 88 }; 89 const struct floatformat floatformat_ieee_single_little = 90 { 91 floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, 92 floatformat_intbit_no, 93 "floatformat_ieee_single_little", 94 floatformat_always_valid, 95 NULL 96 }; 97 const struct floatformat floatformat_ieee_double_big = 98 { 99 floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, 100 floatformat_intbit_no, 101 "floatformat_ieee_double_big", 102 floatformat_always_valid, 103 NULL 104 }; 105 const struct floatformat floatformat_ieee_double_little = 106 { 107 floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, 108 floatformat_intbit_no, 109 "floatformat_ieee_double_little", 110 floatformat_always_valid, 111 NULL 112 }; 113 114 /* floatformat for IEEE double, little endian byte order, with big endian word 115 ordering, as on the ARM. */ 116 117 const struct floatformat floatformat_ieee_double_littlebyte_bigword = 118 { 119 floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, 120 floatformat_intbit_no, 121 "floatformat_ieee_double_littlebyte_bigword", 122 floatformat_always_valid, 123 NULL 124 }; 125 126 /* floatformat for VAX. Not quite IEEE, but close enough. */ 127 128 const struct floatformat floatformat_vax_f = 129 { 130 floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23, 131 floatformat_intbit_no, 132 "floatformat_vax_f", 133 floatformat_always_valid, 134 NULL 135 }; 136 const struct floatformat floatformat_vax_d = 137 { 138 floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55, 139 floatformat_intbit_no, 140 "floatformat_vax_d", 141 floatformat_always_valid, 142 NULL 143 }; 144 const struct floatformat floatformat_vax_g = 145 { 146 floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52, 147 floatformat_intbit_no, 148 "floatformat_vax_g", 149 floatformat_always_valid, 150 NULL 151 }; 152 153 static int floatformat_i387_ext_is_valid (const struct floatformat *fmt, 154 const void *from); 155 156 static int 157 floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from) 158 { 159 /* In the i387 double-extended format, if the exponent is all ones, 160 then the integer bit must be set. If the exponent is neither 0 161 nor ~0, the intbit must also be set. Only if the exponent is 162 zero can it be zero, and then it must be zero. */ 163 unsigned long exponent, int_bit; 164 const unsigned char *ufrom = (const unsigned char *) from; 165 166 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 167 fmt->exp_start, fmt->exp_len); 168 int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize, 169 fmt->man_start, 1); 170 171 if ((exponent == 0) != (int_bit == 0)) 172 return 0; 173 else 174 return 1; 175 } 176 177 const struct floatformat floatformat_i387_ext = 178 { 179 floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 180 floatformat_intbit_yes, 181 "floatformat_i387_ext", 182 floatformat_i387_ext_is_valid, 183 NULL 184 }; 185 const struct floatformat floatformat_m68881_ext = 186 { 187 /* Note that the bits from 16 to 31 are unused. */ 188 floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, 189 floatformat_intbit_yes, 190 "floatformat_m68881_ext", 191 floatformat_always_valid, 192 NULL 193 }; 194 const struct floatformat floatformat_i960_ext = 195 { 196 /* Note that the bits from 0 to 15 are unused. */ 197 floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64, 198 floatformat_intbit_yes, 199 "floatformat_i960_ext", 200 floatformat_always_valid, 201 NULL 202 }; 203 const struct floatformat floatformat_m88110_ext = 204 { 205 floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 206 floatformat_intbit_yes, 207 "floatformat_m88110_ext", 208 floatformat_always_valid, 209 NULL 210 }; 211 const struct floatformat floatformat_m88110_harris_ext = 212 { 213 /* Harris uses raw format 128 bytes long, but the number is just an ieee 214 double, and the last 64 bits are wasted. */ 215 floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52, 216 floatformat_intbit_no, 217 "floatformat_m88110_ext_harris", 218 floatformat_always_valid, 219 NULL 220 }; 221 const struct floatformat floatformat_arm_ext_big = 222 { 223 /* Bits 1 to 16 are unused. */ 224 floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 225 floatformat_intbit_yes, 226 "floatformat_arm_ext_big", 227 floatformat_always_valid, 228 NULL 229 }; 230 const struct floatformat floatformat_arm_ext_littlebyte_bigword = 231 { 232 /* Bits 1 to 16 are unused. */ 233 floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 234 floatformat_intbit_yes, 235 "floatformat_arm_ext_littlebyte_bigword", 236 floatformat_always_valid, 237 NULL 238 }; 239 const struct floatformat floatformat_ia64_spill_big = 240 { 241 floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 242 floatformat_intbit_yes, 243 "floatformat_ia64_spill_big", 244 floatformat_always_valid, 245 NULL 246 }; 247 const struct floatformat floatformat_ia64_spill_little = 248 { 249 floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 250 floatformat_intbit_yes, 251 "floatformat_ia64_spill_little", 252 floatformat_always_valid, 253 NULL 254 }; 255 const struct floatformat floatformat_ia64_quad_big = 256 { 257 floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 258 floatformat_intbit_no, 259 "floatformat_ia64_quad_big", 260 floatformat_always_valid, 261 NULL 262 }; 263 const struct floatformat floatformat_ia64_quad_little = 264 { 265 floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 266 floatformat_intbit_no, 267 "floatformat_ia64_quad_little", 268 floatformat_always_valid, 269 NULL 270 }; 271 272 static int 273 floatformat_ibm_long_double_is_valid (const struct floatformat *fmt, 274 const void *from) 275 { 276 const unsigned char *ufrom = (const unsigned char *) from; 277 const struct floatformat *hfmt = fmt->split_half; 278 long top_exp, bot_exp; 279 int top_nan = 0; 280 281 top_exp = get_field (ufrom, hfmt->byteorder, hfmt->totalsize, 282 hfmt->exp_start, hfmt->exp_len); 283 bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize, 284 hfmt->exp_start, hfmt->exp_len); 285 286 if ((unsigned long) top_exp == hfmt->exp_nan) 287 top_nan = mant_bits_set (hfmt, ufrom); 288 289 /* A NaN is valid with any low part. */ 290 if (top_nan) 291 return 1; 292 293 /* An infinity, zero or denormal requires low part 0 (positive or 294 negative). */ 295 if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0) 296 { 297 if (bot_exp != 0) 298 return 0; 299 300 return !mant_bits_set (hfmt, ufrom + 8); 301 } 302 303 /* The top part is now a finite normal value. The long double value 304 is the sum of the two parts, and the top part must equal the 305 result of rounding the long double value to nearest double. Thus 306 the bottom part must be <= 0.5ulp of the top part in absolute 307 value, and if it is < 0.5ulp then the long double is definitely 308 valid. */ 309 if (bot_exp < top_exp - 53) 310 return 1; 311 if (bot_exp > top_exp - 53 && bot_exp != 0) 312 return 0; 313 if (bot_exp == 0) 314 { 315 /* The bottom part is 0 or denormal. Determine which, and if 316 denormal the first two set bits. */ 317 int first_bit = -1, second_bit = -1, cur_bit; 318 for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++) 319 if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize, 320 hfmt->man_start + cur_bit, 1)) 321 { 322 if (first_bit == -1) 323 first_bit = cur_bit; 324 else 325 { 326 second_bit = cur_bit; 327 break; 328 } 329 } 330 /* Bottom part 0 is OK. */ 331 if (first_bit == -1) 332 return 1; 333 /* The real exponent of the bottom part is -first_bit. */ 334 if (-first_bit < top_exp - 53) 335 return 1; 336 if (-first_bit > top_exp - 53) 337 return 0; 338 /* The bottom part is at least 0.5ulp of the top part. For this 339 to be OK, the bottom part must be exactly 0.5ulp (i.e. no 340 more bits set) and the top part must have last bit 0. */ 341 if (second_bit != -1) 342 return 0; 343 return !get_field (ufrom, hfmt->byteorder, hfmt->totalsize, 344 hfmt->man_start + hfmt->man_len - 1, 1); 345 } 346 else 347 { 348 /* The bottom part is at least 0.5ulp of the top part. For this 349 to be OK, it must be exactly 0.5ulp (i.e. no explicit bits 350 set) and the top part must have last bit 0. */ 351 if (get_field (ufrom, hfmt->byteorder, hfmt->totalsize, 352 hfmt->man_start + hfmt->man_len - 1, 1)) 353 return 0; 354 return !mant_bits_set (hfmt, ufrom + 8); 355 } 356 } 357 358 const struct floatformat floatformat_ibm_long_double = 359 { 360 floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52, 361 floatformat_intbit_no, 362 "floatformat_ibm_long_double", 363 floatformat_ibm_long_double_is_valid, 364 &floatformat_ieee_double_big 365 }; 366 367 368 #ifndef min 369 #define min(a, b) ((a) < (b) ? (a) : (b)) 370 #endif 371 372 /* Return 1 if any bits are explicitly set in the mantissa of UFROM, 373 format FMT, 0 otherwise. */ 374 static int 375 mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom) 376 { 377 unsigned int mant_bits, mant_off; 378 int mant_bits_left; 379 380 mant_off = fmt->man_start; 381 mant_bits_left = fmt->man_len; 382 while (mant_bits_left > 0) 383 { 384 mant_bits = min (mant_bits_left, 32); 385 386 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, 387 mant_off, mant_bits) != 0) 388 return 1; 389 390 mant_off += mant_bits; 391 mant_bits_left -= mant_bits; 392 } 393 return 0; 394 } 395 396 /* Extract a field which starts at START and is LEN bits long. DATA and 397 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 398 static unsigned long 399 get_field (const unsigned char *data, enum floatformat_byteorders order, 400 unsigned int total_len, unsigned int start, unsigned int len) 401 { 402 unsigned long result = 0; 403 unsigned int cur_byte; 404 int lo_bit, hi_bit, cur_bitshift = 0; 405 int nextbyte = (order == floatformat_little) ? 1 : -1; 406 407 /* Start is in big-endian bit order! Fix that first. */ 408 start = total_len - (start + len); 409 410 /* Start at the least significant part of the field. */ 411 if (order == floatformat_little) 412 cur_byte = start / FLOATFORMAT_CHAR_BIT; 413 else 414 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 415 416 lo_bit = start % FLOATFORMAT_CHAR_BIT; 417 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 418 419 do 420 { 421 unsigned int shifted = *(data + cur_byte) >> lo_bit; 422 unsigned int bits = hi_bit - lo_bit; 423 unsigned int mask = (1 << bits) - 1; 424 result |= (shifted & mask) << cur_bitshift; 425 len -= bits; 426 cur_bitshift += bits; 427 cur_byte += nextbyte; 428 lo_bit = 0; 429 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 430 } 431 while (len != 0); 432 433 return result; 434 } 435 436 /* Convert from FMT to a double. 437 FROM is the address of the extended float. 438 Store the double in *TO. */ 439 440 void 441 floatformat_to_double (const struct floatformat *fmt, 442 const void *from, double *to) 443 { 444 const unsigned char *ufrom = (const unsigned char *) from; 445 double dto; 446 long exponent; 447 unsigned long mant; 448 unsigned int mant_bits, mant_off; 449 int mant_bits_left; 450 int special_exponent; /* It's a NaN, denorm or zero */ 451 452 /* Split values are not handled specially, since the top half has 453 the correctly rounded double value (in the only supported case of 454 split values). */ 455 456 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 457 fmt->exp_start, fmt->exp_len); 458 459 /* If the exponent indicates a NaN, we don't have information to 460 decide what to do. So we handle it like IEEE, except that we 461 don't try to preserve the type of NaN. FIXME. */ 462 if ((unsigned long) exponent == fmt->exp_nan) 463 { 464 int nan = mant_bits_set (fmt, ufrom); 465 466 /* On certain systems (such as GNU/Linux), the use of the 467 INFINITY macro below may generate a warning that can not be 468 silenced due to a bug in GCC (PR preprocessor/11931). The 469 preprocessor fails to recognise the __extension__ keyword in 470 conjunction with the GNU/C99 extension for hexadecimal 471 floating point constants and will issue a warning when 472 compiling with -pedantic. */ 473 if (nan) 474 dto = NAN; 475 else 476 #ifdef __vax__ 477 dto = HUGE_VAL; 478 #else 479 dto = INFINITY; 480 #endif 481 482 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 483 dto = -dto; 484 485 *to = dto; 486 487 return; 488 } 489 490 mant_bits_left = fmt->man_len; 491 mant_off = fmt->man_start; 492 dto = 0.0; 493 494 special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan; 495 496 /* Don't bias zero's, denorms or NaNs. */ 497 if (!special_exponent) 498 exponent -= fmt->exp_bias; 499 500 /* Build the result algebraically. Might go infinite, underflow, etc; 501 who cares. */ 502 503 /* If this format uses a hidden bit, explicitly add it in now. Otherwise, 504 increment the exponent by one to account for the integer bit. */ 505 506 if (!special_exponent) 507 { 508 if (fmt->intbit == floatformat_intbit_no) 509 dto = ldexp (1.0, exponent); 510 else 511 exponent++; 512 } 513 514 while (mant_bits_left > 0) 515 { 516 mant_bits = min (mant_bits_left, 32); 517 518 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, 519 mant_off, mant_bits); 520 521 /* Handle denormalized numbers. FIXME: What should we do for 522 non-IEEE formats? */ 523 if (special_exponent && exponent == 0 && mant != 0) 524 dto += ldexp ((double)mant, 525 (- fmt->exp_bias 526 - mant_bits 527 - (mant_off - fmt->man_start) 528 + 1)); 529 else 530 dto += ldexp ((double)mant, exponent - mant_bits); 531 if (exponent != 0) 532 exponent -= mant_bits; 533 mant_off += mant_bits; 534 mant_bits_left -= mant_bits; 535 } 536 537 /* Negate it if negative. */ 538 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 539 dto = -dto; 540 *to = dto; 541 } 542 543 static void put_field (unsigned char *, enum floatformat_byteorders, 544 unsigned int, 545 unsigned int, 546 unsigned int, 547 unsigned long); 548 549 /* Set a field which starts at START and is LEN bits long. DATA and 550 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 551 static void 552 put_field (unsigned char *data, enum floatformat_byteorders order, 553 unsigned int total_len, unsigned int start, unsigned int len, 554 unsigned long stuff_to_put) 555 { 556 unsigned int cur_byte; 557 int lo_bit, hi_bit; 558 int nextbyte = (order == floatformat_little) ? 1 : -1; 559 560 /* Start is in big-endian bit order! Fix that first. */ 561 start = total_len - (start + len); 562 563 /* Start at the least significant part of the field. */ 564 if (order == floatformat_little) 565 cur_byte = start / FLOATFORMAT_CHAR_BIT; 566 else 567 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 568 569 lo_bit = start % FLOATFORMAT_CHAR_BIT; 570 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 571 572 do 573 { 574 unsigned char *byte_ptr = data + cur_byte; 575 unsigned int bits = hi_bit - lo_bit; 576 unsigned int mask = ((1 << bits) - 1) << lo_bit; 577 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask); 578 stuff_to_put >>= bits; 579 len -= bits; 580 cur_byte += nextbyte; 581 lo_bit = 0; 582 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 583 } 584 while (len != 0); 585 } 586 587 /* The converse: convert the double *FROM to an extended float 588 and store where TO points. Neither FROM nor TO have any alignment 589 restrictions. */ 590 591 void 592 floatformat_from_double (const struct floatformat *fmt, 593 const double *from, void *to) 594 { 595 double dfrom; 596 int exponent; 597 double mant; 598 unsigned int mant_bits, mant_off; 599 int mant_bits_left; 600 unsigned char *uto = (unsigned char *) to; 601 602 dfrom = *from; 603 memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); 604 605 /* Split values are not handled specially, since a bottom half of 606 zero is correct for any value representable as double (in the 607 only supported case of split values). */ 608 609 /* If negative, set the sign bit. */ 610 if (dfrom < 0) 611 { 612 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1); 613 dfrom = -dfrom; 614 } 615 616 if (dfrom == 0) 617 { 618 /* 0.0. */ 619 return; 620 } 621 622 if (dfrom != dfrom) 623 { 624 /* NaN. */ 625 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 626 fmt->exp_len, fmt->exp_nan); 627 /* Be sure it's not infinity, but NaN value is irrelevant. */ 628 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start, 629 32, 1); 630 return; 631 } 632 633 if (dfrom + dfrom == dfrom) 634 { 635 /* This can only happen for an infinite value (or zero, which we 636 already handled above). */ 637 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 638 fmt->exp_len, fmt->exp_nan); 639 return; 640 } 641 642 mant = frexp (dfrom, &exponent); 643 if (exponent + fmt->exp_bias - 1 > 0) 644 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 645 fmt->exp_len, exponent + fmt->exp_bias - 1); 646 else 647 { 648 /* Handle a denormalized number. FIXME: What should we do for 649 non-IEEE formats? */ 650 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 651 fmt->exp_len, 0); 652 mant = ldexp (mant, exponent + fmt->exp_bias - 1); 653 } 654 655 mant_bits_left = fmt->man_len; 656 mant_off = fmt->man_start; 657 while (mant_bits_left > 0) 658 { 659 unsigned long mant_long; 660 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; 661 662 mant *= 4294967296.0; 663 mant_long = (unsigned long)mant; 664 mant -= mant_long; 665 666 /* If the integer bit is implicit, and we are not creating a 667 denormalized number, then we need to discard it. */ 668 if ((unsigned int) mant_bits_left == fmt->man_len 669 && fmt->intbit == floatformat_intbit_no 670 && exponent + fmt->exp_bias - 1 > 0) 671 { 672 mant_long &= 0x7fffffff; 673 mant_bits -= 1; 674 } 675 else if (mant_bits < 32) 676 { 677 /* The bits we want are in the most significant MANT_BITS bits of 678 mant_long. Move them to the least significant. */ 679 mant_long >>= 32 - mant_bits; 680 } 681 682 put_field (uto, fmt->byteorder, fmt->totalsize, 683 mant_off, mant_bits, mant_long); 684 mant_off += mant_bits; 685 mant_bits_left -= mant_bits; 686 } 687 } 688 689 /* Return non-zero iff the data at FROM is a valid number in format FMT. */ 690 691 int 692 floatformat_is_valid (const struct floatformat *fmt, const void *from) 693 { 694 return fmt->is_valid (fmt, from); 695 } 696 697 698 #ifdef IEEE_DEBUG 699 700 #include <stdio.h> 701 702 /* This is to be run on a host which uses IEEE floating point. */ 703 704 void 705 ieee_test (double n) 706 { 707 double result; 708 709 floatformat_to_double (&floatformat_ieee_double_little, &n, &result); 710 if ((n != result && (! isnan (n) || ! isnan (result))) 711 || (n < 0 && result >= 0) 712 || (n >= 0 && result < 0)) 713 printf ("Differ(to): %.20g -> %.20g\n", n, result); 714 715 floatformat_from_double (&floatformat_ieee_double_little, &n, &result); 716 if ((n != result && (! isnan (n) || ! isnan (result))) 717 || (n < 0 && result >= 0) 718 || (n >= 0 && result < 0)) 719 printf ("Differ(from): %.20g -> %.20g\n", n, result); 720 721 #if 0 722 { 723 char exten[16]; 724 725 floatformat_from_double (&floatformat_m68881_ext, &n, exten); 726 floatformat_to_double (&floatformat_m68881_ext, exten, &result); 727 if (n != result) 728 printf ("Differ(to+from): %.20g -> %.20g\n", n, result); 729 } 730 #endif 731 732 #if IEEE_DEBUG > 1 733 /* This is to be run on a host which uses 68881 format. */ 734 { 735 long double ex = *(long double *)exten; 736 if (ex != n) 737 printf ("Differ(from vs. extended): %.20g\n", n); 738 } 739 #endif 740 } 741 742 int 743 main (void) 744 { 745 ieee_test (0.0); 746 ieee_test (0.5); 747 ieee_test (256.0); 748 ieee_test (0.12345); 749 ieee_test (234235.78907234); 750 ieee_test (-512.0); 751 ieee_test (-0.004321); 752 ieee_test (1.2E-70); 753 ieee_test (1.2E-316); 754 ieee_test (4.9406564584124654E-324); 755 ieee_test (- 4.9406564584124654E-324); 756 ieee_test (- 0.0); 757 ieee_test (- INFINITY); 758 ieee_test (- NAN); 759 ieee_test (INFINITY); 760 ieee_test (NAN); 761 return 0; 762 } 763 #endif 764