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