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

Last change on this file since 27306 was 27306, checked in by Ivan Raikov, 9 years ago

endian-blob: fixing ansidecl.h issue again

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