floatformat.c revision 1.1.1.1.8.2 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
369 #ifndef min
370 #define min(a, b) ((a) < (b) ? (a) : (b))
371 #endif
372
373 /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
374 format FMT, 0 otherwise. */
375 static int
376 mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
377 {
378 unsigned int mant_bits, mant_off;
379 int mant_bits_left;
380
381 mant_off = fmt->man_start;
382 mant_bits_left = fmt->man_len;
383 while (mant_bits_left > 0)
384 {
385 mant_bits = min (mant_bits_left, 32);
386
387 if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
388 mant_off, mant_bits) != 0)
389 return 1;
390
391 mant_off += mant_bits;
392 mant_bits_left -= mant_bits;
393 }
394 return 0;
395 }
396
397 /* Extract a field which starts at START and is LEN bits long. DATA and
398 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
399 static unsigned long
400 get_field (const unsigned char *data, enum floatformat_byteorders order,
401 unsigned int total_len, unsigned int start, unsigned int len)
402 {
403 unsigned long result = 0;
404 unsigned int cur_byte;
405 int lo_bit, hi_bit, cur_bitshift = 0;
406 int nextbyte = (order == floatformat_little) ? 1 : -1;
407
408 /* Start is in big-endian bit order! Fix that first. */
409 start = total_len - (start + len);
410
411 /* Start at the least significant part of the field. */
412 if (order == floatformat_little)
413 cur_byte = start / FLOATFORMAT_CHAR_BIT;
414 else
415 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
416
417 lo_bit = start % FLOATFORMAT_CHAR_BIT;
418 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
419
420 do
421 {
422 unsigned int shifted = *(data + cur_byte) >> lo_bit;
423 unsigned int bits = hi_bit - lo_bit;
424 unsigned int mask = (1 << bits) - 1;
425 result |= (shifted & mask) << cur_bitshift;
426 len -= bits;
427 cur_bitshift += bits;
428 cur_byte += nextbyte;
429 lo_bit = 0;
430 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
431 }
432 while (len != 0);
433
434 return result;
435 }
436
437 /* Convert from FMT to a double.
438 FROM is the address of the extended float.
439 Store the double in *TO. */
440
441 void
442 floatformat_to_double (const struct floatformat *fmt,
443 const void *from, double *to)
444 {
445 const unsigned char *ufrom = (const unsigned char *) from;
446 double dto;
447 long exponent;
448 unsigned long mant;
449 unsigned int mant_bits, mant_off;
450 int mant_bits_left;
451 int special_exponent; /* It's a NaN, denorm or zero */
452
453 /* Split values are not handled specially, since the top half has
454 the correctly rounded double value (in the only supported case of
455 split values). */
456
457 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
458 fmt->exp_start, fmt->exp_len);
459
460 /* If the exponent indicates a NaN, we don't have information to
461 decide what to do. So we handle it like IEEE, except that we
462 don't try to preserve the type of NaN. FIXME. */
463 if ((unsigned long) exponent == fmt->exp_nan)
464 {
465 int nan = mant_bits_set (fmt, ufrom);
466
467 /* On certain systems (such as GNU/Linux), the use of the
468 INFINITY macro below may generate a warning that can not be
469 silenced due to a bug in GCC (PR preprocessor/11931). The
470 preprocessor fails to recognise the __extension__ keyword in
471 conjunction with the GNU/C99 extension for hexadecimal
472 floating point constants and will issue a warning when
473 compiling with -pedantic. */
474 if (nan)
475 dto = NAN;
476 else
477 #ifdef __vax__
478 dto = HUGE_VAL;
479 #else
480 dto = INFINITY;
481 #endif
482
483 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
484 dto = -dto;
485
486 *to = dto;
487
488 return;
489 }
490
491 mant_bits_left = fmt->man_len;
492 mant_off = fmt->man_start;
493 dto = 0.0;
494
495 special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
496
497 /* Don't bias zero's, denorms or NaNs. */
498 if (!special_exponent)
499 exponent -= fmt->exp_bias;
500
501 /* Build the result algebraically. Might go infinite, underflow, etc;
502 who cares. */
503
504 /* If this format uses a hidden bit, explicitly add it in now. Otherwise,
505 increment the exponent by one to account for the integer bit. */
506
507 if (!special_exponent)
508 {
509 if (fmt->intbit == floatformat_intbit_no)
510 dto = ldexp (1.0, exponent);
511 else
512 exponent++;
513 }
514
515 while (mant_bits_left > 0)
516 {
517 mant_bits = min (mant_bits_left, 32);
518
519 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
520 mant_off, mant_bits);
521
522 /* Handle denormalized numbers. FIXME: What should we do for
523 non-IEEE formats? */
524 if (special_exponent && exponent == 0 && mant != 0)
525 dto += ldexp ((double)mant,
526 (- fmt->exp_bias
527 - mant_bits
528 - (mant_off - fmt->man_start)
529 + 1));
530 else
531 dto += ldexp ((double)mant, exponent - mant_bits);
532 if (exponent != 0)
533 exponent -= mant_bits;
534 mant_off += mant_bits;
535 mant_bits_left -= mant_bits;
536 }
537
538 /* Negate it if negative. */
539 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
540 dto = -dto;
541 *to = dto;
542 }
543
544 static void put_field (unsigned char *, enum floatformat_byteorders,
546 unsigned int,
547 unsigned int,
548 unsigned int,
549 unsigned long);
550
551 /* Set a field which starts at START and is LEN bits long. DATA and
552 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
553 static void
554 put_field (unsigned char *data, enum floatformat_byteorders order,
555 unsigned int total_len, unsigned int start, unsigned int len,
556 unsigned long stuff_to_put)
557 {
558 unsigned int cur_byte;
559 int lo_bit, hi_bit;
560 int nextbyte = (order == floatformat_little) ? 1 : -1;
561
562 /* Start is in big-endian bit order! Fix that first. */
563 start = total_len - (start + len);
564
565 /* Start at the least significant part of the field. */
566 if (order == floatformat_little)
567 cur_byte = start / FLOATFORMAT_CHAR_BIT;
568 else
569 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
570
571 lo_bit = start % FLOATFORMAT_CHAR_BIT;
572 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
573
574 do
575 {
576 unsigned char *byte_ptr = data + cur_byte;
577 unsigned int bits = hi_bit - lo_bit;
578 unsigned int mask = ((1 << bits) - 1) << lo_bit;
579 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
580 stuff_to_put >>= bits;
581 len -= bits;
582 cur_byte += nextbyte;
583 lo_bit = 0;
584 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
585 }
586 while (len != 0);
587 }
588
589 /* The converse: convert the double *FROM to an extended float
590 and store where TO points. Neither FROM nor TO have any alignment
591 restrictions. */
592
593 void
594 floatformat_from_double (const struct floatformat *fmt,
595 const double *from, void *to)
596 {
597 double dfrom;
598 int exponent;
599 double mant;
600 unsigned int mant_bits, mant_off;
601 int mant_bits_left;
602 unsigned char *uto = (unsigned char *) to;
603
604 dfrom = *from;
605 memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
606
607 /* Split values are not handled specially, since a bottom half of
608 zero is correct for any value representable as double (in the
609 only supported case of split values). */
610
611 /* If negative, set the sign bit. */
612 if (dfrom < 0)
613 {
614 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
615 dfrom = -dfrom;
616 }
617
618 if (dfrom == 0)
619 {
620 /* 0.0. */
621 return;
622 }
623
624 if (dfrom != dfrom)
625 {
626 /* NaN. */
627 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
628 fmt->exp_len, fmt->exp_nan);
629 /* Be sure it's not infinity, but NaN value is irrelevant. */
630 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
631 32, 1);
632 return;
633 }
634
635 if (dfrom + dfrom == dfrom)
636 {
637 /* This can only happen for an infinite value (or zero, which we
638 already handled above). */
639 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
640 fmt->exp_len, fmt->exp_nan);
641 return;
642 }
643
644 mant = frexp (dfrom, &exponent);
645 if (exponent + fmt->exp_bias - 1 > 0)
646 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
647 fmt->exp_len, exponent + fmt->exp_bias - 1);
648 else
649 {
650 /* Handle a denormalized number. FIXME: What should we do for
651 non-IEEE formats? */
652 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
653 fmt->exp_len, 0);
654 mant = ldexp (mant, exponent + fmt->exp_bias - 1);
655 }
656
657 mant_bits_left = fmt->man_len;
658 mant_off = fmt->man_start;
659 while (mant_bits_left > 0)
660 {
661 unsigned long mant_long;
662 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
663
664 mant *= 4294967296.0;
665 mant_long = (unsigned long)mant;
666 mant -= mant_long;
667
668 /* If the integer bit is implicit, and we are not creating a
669 denormalized number, then we need to discard it. */
670 if ((unsigned int) mant_bits_left == fmt->man_len
671 && fmt->intbit == floatformat_intbit_no
672 && exponent + fmt->exp_bias - 1 > 0)
673 {
674 mant_long &= 0x7fffffff;
675 mant_bits -= 1;
676 }
677 else if (mant_bits < 32)
678 {
679 /* The bits we want are in the most significant MANT_BITS bits of
680 mant_long. Move them to the least significant. */
681 mant_long >>= 32 - mant_bits;
682 }
683
684 put_field (uto, fmt->byteorder, fmt->totalsize,
685 mant_off, mant_bits, mant_long);
686 mant_off += mant_bits;
687 mant_bits_left -= mant_bits;
688 }
689 }
690
691 /* Return non-zero iff the data at FROM is a valid number in format FMT. */
692
693 int
694 floatformat_is_valid (const struct floatformat *fmt, const void *from)
695 {
696 return fmt->is_valid (fmt, from);
697 }
698
699
700 #ifdef IEEE_DEBUG
701
702 #include <stdio.h>
703
704 /* This is to be run on a host which uses IEEE floating point. */
705
706 void
707 ieee_test (double n)
708 {
709 double result;
710
711 floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
712 if ((n != result && (! isnan (n) || ! isnan (result)))
713 || (n < 0 && result >= 0)
714 || (n >= 0 && result < 0))
715 printf ("Differ(to): %.20g -> %.20g\n", n, result);
716
717 floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
718 if ((n != result && (! isnan (n) || ! isnan (result)))
719 || (n < 0 && result >= 0)
720 || (n >= 0 && result < 0))
721 printf ("Differ(from): %.20g -> %.20g\n", n, result);
722
723 #if 0
724 {
725 char exten[16];
726
727 floatformat_from_double (&floatformat_m68881_ext, &n, exten);
728 floatformat_to_double (&floatformat_m68881_ext, exten, &result);
729 if (n != result)
730 printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
731 }
732 #endif
733
734 #if IEEE_DEBUG > 1
735 /* This is to be run on a host which uses 68881 format. */
736 {
737 long double ex = *(long double *)exten;
738 if (ex != n)
739 printf ("Differ(from vs. extended): %.20g\n", n);
740 }
741 #endif
742 }
743
744 int
745 main (void)
746 {
747 ieee_test (0.0);
748 ieee_test (0.5);
749 ieee_test (256.0);
750 ieee_test (0.12345);
751 ieee_test (234235.78907234);
752 ieee_test (-512.0);
753 ieee_test (-0.004321);
754 ieee_test (1.2E-70);
755 ieee_test (1.2E-316);
756 ieee_test (4.9406564584124654E-324);
757 ieee_test (- 4.9406564584124654E-324);
758 ieee_test (- 0.0);
759 ieee_test (- INFINITY);
760 ieee_test (- NAN);
761 ieee_test (INFINITY);
762 ieee_test (NAN);
763 return 0;
764 }
765 #endif
766