source: project/release/4/endian-blob/trunk/floatformat.c @ 16141

Last change on this file since 16141 was 16141, checked in by Ivan Raikov, 12 years ago

initial import of endian-blob

File size: 20.0 KB
Line 
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
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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#include <stdlib.h>
25#include <math.h>
26#include <string.h>
27
28/* On some platforms, <float.h> provides DBL_QNAN.  */
29#ifdef STDC_HEADERS
30#include <float.h>
31#endif
32
33#include "ansidecl.h"
34#include "floatformat.h"
35
36#ifndef INFINITY
37#ifdef HUGE_VAL
38#define INFINITY HUGE_VAL
39#else
40#define INFINITY (1.0 / 0.0)
41#endif
42#endif
43
44#ifndef NAN
45#ifdef DBL_QNAN
46#define NAN DBL_QNAN
47#else
48#define NAN (0.0 / 0.0)
49#endif
50#endif
51
52unsigned long get_field (const unsigned char *,
53                         enum floatformat_byteorders,
54                         unsigned int,
55                         unsigned int,
56                         unsigned int);
57
58static int floatformat_always_valid (const struct floatformat *fmt,
59                                     const void *from);
60
61static int
62floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
63                          const void *from ATTRIBUTE_UNUSED)
64{
65  return 1;
66}
67
68/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
69   going to bother with trying to muck around with whether it is defined in
70   a system header, what we do if not, etc.  */
71#define FLOATFORMAT_CHAR_BIT 8
72
73/* floatformats for IEEE single and double, big and little endian.  */
74const struct floatformat floatformat_ieee_single_big =
75{
76  floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
77  floatformat_intbit_no,
78  "floatformat_ieee_single_big",
79  floatformat_always_valid
80};
81const struct floatformat floatformat_ieee_single_little =
82{
83  floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
84  floatformat_intbit_no,
85  "floatformat_ieee_single_little",
86  floatformat_always_valid
87};
88const struct floatformat floatformat_ieee_double_big =
89{
90  floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
91  floatformat_intbit_no,
92  "floatformat_ieee_double_big",
93  floatformat_always_valid
94};
95const struct floatformat floatformat_ieee_double_little =
96{
97  floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
98  floatformat_intbit_no,
99  "floatformat_ieee_double_little",
100  floatformat_always_valid
101};
102
103/* floatformat for IEEE double, little endian byte order, with big endian word
104   ordering, as on the ARM.  */
105
106const struct floatformat floatformat_ieee_double_littlebyte_bigword =
107{
108  floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
109  floatformat_intbit_no,
110  "floatformat_ieee_double_littlebyte_bigword",
111  floatformat_always_valid
112};
113
114/* floatformat for VAX.  Not quite IEEE, but close enough.  */
115
116const struct floatformat floatformat_vax_f =
117{
118  floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
119  floatformat_intbit_no,
120  "floatformat_vax_f",
121  floatformat_always_valid
122};
123const struct floatformat floatformat_vax_d =
124{
125  floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
126  floatformat_intbit_no,
127  "floatformat_vax_d",
128  floatformat_always_valid
129};
130const struct floatformat floatformat_vax_g =
131{
132  floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
133  floatformat_intbit_no,
134  "floatformat_vax_g",
135  floatformat_always_valid
136};
137
138static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
139                                          const void *from);
140
141static int
142floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
143{
144  /* In the i387 double-extended format, if the exponent is all ones,
145     then the integer bit must be set.  If the exponent is neither 0
146     nor ~0, the intbit must also be set.  Only if the exponent is
147     zero can it be zero, and then it must be zero.  */
148  unsigned long exponent, int_bit;
149  const unsigned char *ufrom = from;
150
151  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
152                        fmt->exp_start, fmt->exp_len);
153  int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
154                       fmt->man_start, 1);
155
156  if ((exponent == 0) != (int_bit == 0))
157    return 0;
158  else
159    return 1;
160}
161
162const struct floatformat floatformat_i387_ext =
163{
164  floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
165  floatformat_intbit_yes,
166  "floatformat_i387_ext",
167  floatformat_i387_ext_is_valid
168};
169const struct floatformat floatformat_m68881_ext =
170{
171  /* Note that the bits from 16 to 31 are unused.  */
172  floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
173  floatformat_intbit_yes,
174  "floatformat_m68881_ext",
175  floatformat_always_valid
176};
177const struct floatformat floatformat_i960_ext =
178{
179  /* Note that the bits from 0 to 15 are unused.  */
180  floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
181  floatformat_intbit_yes,
182  "floatformat_i960_ext",
183  floatformat_always_valid
184};
185const struct floatformat floatformat_m88110_ext =
186{
187  floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
188  floatformat_intbit_yes,
189  "floatformat_m88110_ext",
190  floatformat_always_valid
191};
192const struct floatformat floatformat_m88110_harris_ext =
193{
194  /* Harris uses raw format 128 bytes long, but the number is just an ieee
195     double, and the last 64 bits are wasted. */
196  floatformat_big,128, 0, 1, 11,  0x3ff,  0x7ff, 12, 52,
197  floatformat_intbit_no,
198  "floatformat_m88110_ext_harris",
199  floatformat_always_valid
200};
201const struct floatformat floatformat_arm_ext_big =
202{
203  /* Bits 1 to 16 are unused.  */
204  floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
205  floatformat_intbit_yes,
206  "floatformat_arm_ext_big",
207  floatformat_always_valid
208};
209const struct floatformat floatformat_arm_ext_littlebyte_bigword =
210{
211  /* Bits 1 to 16 are unused.  */
212  floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
213  floatformat_intbit_yes,
214  "floatformat_arm_ext_littlebyte_bigword",
215  floatformat_always_valid
216};
217const struct floatformat floatformat_ia64_spill_big =
218{
219  floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
220  floatformat_intbit_yes,
221  "floatformat_ia64_spill_big",
222  floatformat_always_valid
223};
224const struct floatformat floatformat_ia64_spill_little =
225{
226  floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
227  floatformat_intbit_yes,
228  "floatformat_ia64_spill_little",
229  floatformat_always_valid
230};
231const struct floatformat floatformat_ia64_quad_big =
232{
233  floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
234  floatformat_intbit_no,
235  "floatformat_ia64_quad_big",
236  floatformat_always_valid
237};
238const struct floatformat floatformat_ia64_quad_little =
239{
240  floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
241  floatformat_intbit_no,
242  "floatformat_ia64_quad_little",
243  floatformat_always_valid
244};
245
246/* Extract a field which starts at START and is LEN bytes long.  DATA and
247   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
248unsigned long
249get_field (const unsigned char *data, enum floatformat_byteorders order,
250           unsigned int total_len, unsigned int start, unsigned int len)
251{
252  unsigned long result;
253  unsigned int cur_byte;
254  int cur_bitshift;
255
256  /* Start at the least significant part of the field.  */
257  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
258    {
259      /* We start counting from the other end (i.e, from the high bytes
260         rather than the low bytes).  As such, we need to be concerned
261         with what happens if bit 0 doesn't start on a byte boundary.
262         I.e, we need to properly handle the case where total_len is
263         not evenly divisible by 8.  So we compute ``excess'' which
264         represents the number of bits from the end of our starting
265         byte needed to get to bit 0. */
266      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
267      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 
268                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
269      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 
270                     - FLOATFORMAT_CHAR_BIT;
271    }
272  else
273    {
274      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
275      cur_bitshift =
276        ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
277    }
278  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
279    result = *(data + cur_byte) >> (-cur_bitshift);
280  else
281    result = 0;
282  cur_bitshift += FLOATFORMAT_CHAR_BIT;
283  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
284    ++cur_byte;
285  else
286    --cur_byte;
287
288  /* Move towards the most significant part of the field.  */
289  while (cur_bitshift < len)
290    {
291      result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
292      cur_bitshift += FLOATFORMAT_CHAR_BIT;
293      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
294        ++cur_byte;
295      else
296        --cur_byte;
297    }
298  if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
299    /* Mask out bits which are not part of the field */
300    result &= ((1UL << len) - 1);
301  return result;
302}
303
304 
305#ifndef min
306#define min(a, b) ((a) < (b) ? (a) : (b))
307#endif
308
309/* Convert from FMT to a double
310   FROM is the address of the extended float.
311   Store the double in *TO.  */
312
313void 
314floatformat_to_double (const struct floatformat *fmt,
315                       const void *from,
316                       double *to)
317{
318  unsigned char *ufrom = (unsigned char *) from;
319  double dto;
320  long exponent;
321  unsigned long mant;
322  unsigned int mant_bits, mant_off;
323  int mant_bits_left;
324  int special_exponent;         /* It's a NaN, denorm or zero */
325
326  /* If the mantissa bits are not contiguous from one end of the
327     mantissa to the other, we need to make a private copy of the
328     source bytes that is in the right order since the unpacking
329     algorithm assumes that the bits are contiguous.
330
331     Swap the bytes individually rather than accessing them through
332     "long *" since we have no guarantee that they start on a long
333     alignment, and also sizeof(long) for the host could be different
334     than sizeof(long) for the target.  FIXME: Assumes sizeof(long)
335     for the target is 4. */
336
337  if (fmt->byteorder == floatformat_littlebyte_bigword)
338    {
339      static unsigned char *newfrom;
340      unsigned char *swapin, *swapout;
341      int longswaps;
342
343      longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
344      longswaps >>= 3;
345
346      if (newfrom == NULL)
347        {
348          newfrom = (unsigned char *) malloc (fmt->totalsize);
349        }
350      swapout = newfrom;
351      swapin = ufrom;
352      ufrom = newfrom;
353      while (longswaps-- > 0)
354        {
355          /* This is ugly, but efficient */
356          *swapout++ = swapin[4];
357          *swapout++ = swapin[5];
358          *swapout++ = swapin[6];
359          *swapout++ = swapin[7];
360          *swapout++ = swapin[0];
361          *swapout++ = swapin[1];
362          *swapout++ = swapin[2];
363          *swapout++ = swapin[3];
364          swapin += 8;
365        }
366    }
367
368  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
369                        fmt->exp_start, fmt->exp_len);
370  /* Note that if exponent indicates a NaN, we can't really do anything useful
371     (not knowing if the host has NaN's, or how to build one).  So it will
372     end up as an infinity or something close; that is OK.  */
373
374  mant_bits_left = fmt->man_len;
375  mant_off = fmt->man_start;
376  dto = 0.0;
377
378  special_exponent = exponent == 0 || exponent == fmt->exp_nan;
379
380  /* Don't bias NaNs. Use minimum exponent for denorms. For simplicity,
381     we don't check for zero as the exponent doesn't matter.  Note the cast
382     to int; exp_bias is unsigned, so it's important to make sure the
383     operation is done in signed arithmetic.  */
384  if (!special_exponent)
385    exponent -= fmt->exp_bias;
386  else if (exponent == 0)
387    exponent = 1 - fmt->exp_bias;
388
389  /* Build the result algebraically.  Might go infinite, underflow, etc;
390     who cares. */
391
392/* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
393   increment the exponent by one to account for the integer bit.  */
394
395  if (!special_exponent)
396    {
397      if (fmt->intbit == floatformat_intbit_no)
398        dto = ldexp (1.0, exponent);
399      else
400        exponent++;
401    }
402
403  while (mant_bits_left > 0)
404    {
405      mant_bits = min (mant_bits_left, 32);
406
407      mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
408                        mant_off, mant_bits);
409
410      dto += ldexp ((double) mant, exponent - mant_bits);
411      exponent -= mant_bits;
412      mant_off += mant_bits;
413      mant_bits_left -= mant_bits;
414    }
415
416  /* Negate it if negative.  */
417  if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
418    dto = -dto;
419  *to = dto;
420}
421
422/* Set a field which starts at START and is LEN bytes long.  DATA and
423   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
424static void
425put_field (unsigned char *data, enum floatformat_byteorders order,
426           unsigned int total_len, unsigned int start, unsigned int len,
427           unsigned long stuff_to_put)
428{
429  unsigned int cur_byte;
430  int cur_bitshift;
431
432  /* Start at the least significant part of the field.  */
433  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
434    {
435      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
436      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 
437                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
438      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 
439                     - FLOATFORMAT_CHAR_BIT;
440    }
441  else
442    {
443      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
444      cur_bitshift =
445        ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
446    }
447  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
448    {
449      *(data + cur_byte) &=
450        ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
451          << (-cur_bitshift));
452      *(data + cur_byte) |=
453        (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
454    }
455  cur_bitshift += FLOATFORMAT_CHAR_BIT;
456  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
457    ++cur_byte;
458  else
459    --cur_byte;
460
461  /* Move towards the most significant part of the field.  */
462  while (cur_bitshift < len)
463    {
464      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
465        {
466          /* This is the last byte.  */
467          *(data + cur_byte) &=
468            ~((1 << (len - cur_bitshift)) - 1);
469          *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
470        }
471      else
472        *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
473                              & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
474      cur_bitshift += FLOATFORMAT_CHAR_BIT;
475      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
476        ++cur_byte;
477      else
478        --cur_byte;
479    }
480}
481
482
483
484
485/* The converse: convert the double *FROM to an extended float
486   and store where TO points.  Neither FROM nor TO have any alignment
487   restrictions.  */
488
489void
490double_to_floatformat (const struct floatformat *fmt,
491                       const double *from,
492                       void *to)
493{
494  double dfrom;
495  int exponent;
496  double mant;
497  unsigned int mant_bits, mant_off;
498  int mant_bits_left;
499  unsigned char *uto = (unsigned char *) to;
500
501  memcpy (&dfrom, from, sizeof (dfrom));
502  memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) 
503                    / FLOATFORMAT_CHAR_BIT);
504  if (dfrom == 0)
505    return;                     /* Result is zero */
506  if (dfrom != dfrom)           /* Result is NaN */
507    {
508      /* From is NaN */
509      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
510                 fmt->exp_len, fmt->exp_nan);
511      /* Be sure it's not infinity, but NaN value is irrel */
512      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
513                 32, 1);
514      return;
515    }
516
517  /* If negative, set the sign bit.  */
518  if (dfrom < 0)
519    {
520      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
521      dfrom = -dfrom;
522    }
523
524  if (dfrom + dfrom == dfrom && dfrom != 0.0)   /* Result is Infinity */
525    {
526      /* Infinity exponent is same as NaN's.  */
527      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
528                 fmt->exp_len, fmt->exp_nan);
529      /* Infinity mantissa is all zeroes.  */
530      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
531                 fmt->man_len, 0);
532      return;
533    }
534
535  mant = frexp (dfrom, &exponent);
536
537  if (exponent + fmt->exp_bias - 1 > 0)
538       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
539                  fmt->exp_len, exponent + fmt->exp_bias - 1);
540  else
541  {
542       /* Handle a denormalized number.  FIXME: What should we do for
543          non-IEEE formats?  */
544       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
545                  fmt->exp_len, 0);
546       mant = ldexp (mant, exponent + fmt->exp_bias - 1);
547  }
548
549  mant_bits_left = fmt->man_len;
550  mant_off = fmt->man_start;
551  while (mant_bits_left > 0)
552    {
553         unsigned long mant_long;
554
555         mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
556         
557         mant *= 4294967296.0;
558         mant_long = ((unsigned long) mant) & 0xffffffffL;
559         mant -= mant_long;
560         
561         /* If the integer bit is implicit, and we are not creating a
562            denormalized number, then we need to discard it.  */
563         if (mant_bits_left == fmt->man_len
564             && fmt->intbit == floatformat_intbit_no
565             && exponent + fmt->exp_bias - 1 > 0)
566         {
567              mant_long <<= 1;
568              mant_long &= 0xffffffffL;
569
570              if (mant_bits == 32)
571                   mant_bits -= 1;
572         }
573         
574         if (mant_bits < 32)
575         {
576              /* The bits we want are in the most significant MANT_BITS bits of
577                 mant_long.  Move them to the least significant.  */
578              mant_long >>= 32 - mant_bits;
579         }
580         
581         
582         put_field (uto, fmt->byteorder, fmt->totalsize,
583                    mant_off, mant_bits, mant_long);
584         mant_off += mant_bits;
585         mant_bits_left -= mant_bits;
586    }
587 
588     if (fmt->byteorder == floatformat_littlebyte_bigword)
589     {
590          int count;
591          unsigned char *swaplow = uto;
592          unsigned char *swaphigh = uto + 4;
593          unsigned char tmp;
594         
595          for (count = 0; count < 4; count++)
596          {
597               tmp = *swaplow;
598               *swaplow++ = *swaphigh;
599               *swaphigh++ = tmp;
600          }
601     }
602}
603
604
605
606/* Return non-zero iff the data at FROM is a valid number in format FMT.  */
607
608int
609floatformat_is_valid (const struct floatformat *fmt, const void *from)
610{
611  return fmt->is_valid (fmt, from);
612}
613
614
615#ifdef IEEE_DEBUG
616
617#include <stdio.h>
618
619/* This is to be run on a host which uses IEEE floating point.  */
620
621void
622ieee_test (double n)
623{
624  double result;
625  float s;
626
627  floatformat_to_double (&floatformat_ieee_single_big, &n, &s);
628  if ((n != s && (! isnan (n) || ! isnan (s)))
629      || (n < 0 && s >= 0)
630      || (n >= 0 && s < 0))
631    printf ("IEEE single: differ(to): %.20g -> %.20g\n", n, s);
632
633  double_to_floatformat (&floatformat_ieee_single_big, &n, &result, 1);
634  if ((n != result && (! isnan (n) || ! isnan (result)))
635      || (n < 0 && result >= 0)
636      || (n >= 0 && result < 0))
637    printf ("IEEE single: differ(from): %.20g -> %.20g\n", n, result);
638
639  floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
640  if ((n != result && (! isnan (n) || ! isnan (result)))
641      || (n < 0 && result >= 0)
642      || (n >= 0 && result < 0))
643    printf ("IEEE double: differ(to): %.20g -> %.20g\n", n, result);
644
645  double_to_floatformat (&floatformat_ieee_double_little, &n, &result, 1);
646  if ((n != result && (! isnan (n) || ! isnan (result)))
647      || (n < 0 && result >= 0)
648      || (n >= 0 && result < 0))
649    printf ("IEEE double: differ(from): %.20g -> %.20g\n", n, result);
650
651#if 0
652  {
653    char exten[16];
654
655    floatformat_from_double (&floatformat_m68881_ext, &n, exten);
656    floatformat_to_double (&floatformat_m68881_ext, exten, &result);
657    if (n != result)
658      printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
659  }
660#endif
661
662#if IEEE_DEBUG > 1
663  /* This is to be run on a host which uses 68881 format.  */
664  {
665    long double ex = *(long double *)exten;
666    if (ex != n)
667      printf ("Differ(from vs. extended): %.20g\n", n);
668  }
669#endif
670}
671
672int
673main (void)
674{
675  ieee_test (0.0);
676  ieee_test (0.5);
677  ieee_test (3.0);
678  ieee_test (256.0);
679  ieee_test (0.12345);
680  ieee_test (234235.78907234);
681  ieee_test (-512.0);
682  ieee_test (-0.004321);
683  ieee_test (1.2E-70);
684  ieee_test (1.2E-316);
685  ieee_test (4.9406564584124654E-324);
686  ieee_test (- 4.9406564584124654E-324);
687  ieee_test (- 0.0);
688  ieee_test (- INFINITY);
689  ieee_test (- NAN);
690  ieee_test (INFINITY);
691  ieee_test (NAN);
692  return 0;
693}
694#endif
Note: See TracBrowser for help on using the repository browser.