home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / common / extended.c < prev    next >
C/C++ Source or Header  |  2001-10-26  |  6KB  |  193 lines

  1. #include "wx/setup.h"
  2.  
  3. #include <math.h>
  4.  
  5. #if wxUSE_APPLE_IEEE
  6.  
  7. /*
  8.  * C O N V E R T   T O     I E E E   E X T E N D E D
  9.  */
  10.  
  11. /* Copyright (C) 1988-1991 Apple Computer, Inc.
  12.  * All rights reserved.
  13.  *
  14.  * Machine-independent I/O routines for IEEE floating-point numbers.
  15.  *
  16.  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  17.  * happens to be infinity on IEEE machines.     Unfortunately, it is
  18.  * impossible to preserve NaN's in a machine-independent way.
  19.  * Infinities are, however, preserved on IEEE machines.
  20.  *
  21.  * These routines have been tested on the following machines:
  22.  *    Apple Macintosh, MPW 3.1 C compiler
  23.  *    Apple Macintosh, THINK C compiler
  24.  *    Silicon Graphics IRIS, MIPS compiler
  25.  *    Cray X/MP and Y/MP
  26.  *    Digital Equipment VAX
  27.  *
  28.  *
  29.  * Implemented by Malcolm Slaney and Ken Turkowski.
  30.  *
  31.  * Malcolm Slaney contributions during 1988-1990 include big- and little-
  32.  * endian file I/O, conversion to and from Motorola's extended 80-bit
  33.  * floating-point format, and conversions to and from IEEE single-
  34.  * precision floating-point format.
  35.  *
  36.  * In 1991, Ken Turkowski implemented the conversions to and from
  37.  * IEEE double-precision format, added more precision to the extended
  38.  * conversions, and accommodated conversions involving +/- infinity,
  39.  * NaN's, and denormalized numbers.
  40.  */
  41.  
  42. #ifndef HUGE_VAL
  43. #define HUGE_VAL HUGE
  44. #endif /*HUGE_VAL*/
  45.  
  46. #define FloatToUnsigned(f) ((unsigned long) (((long) (f - 2147483648.0)) + 2147483647L) + 1)
  47.  
  48. void ConvertToIeeeExtended(double num, unsigned char *bytes)
  49. {
  50.     int                sign;
  51.     int                expon;
  52.     double            fMant, fsMant;
  53.     unsigned long    hiMant, loMant;
  54.  
  55.     if (num < 0) {
  56.         sign = 0x8000;
  57.         num *= -1;
  58.     } else {
  59.         sign = 0;
  60.     }
  61.  
  62.     if (num == 0) {
  63.         expon = 0; hiMant = 0; loMant = 0;
  64.     }
  65.     else {
  66.         fMant = frexp(num, &expon);
  67.         if ((expon > 16384) || !(fMant < 1)) {      /* Infinity or NaN */
  68.             expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
  69.         }
  70.         else {      /* Finite */
  71.             expon += 16382;
  72.             if (expon < 0) {    /* denormalized */
  73.                 fMant = ldexp(fMant, expon);
  74.                 expon = 0;
  75.             }
  76.             expon |= sign;
  77.             fMant = ldexp(fMant, 32);
  78.             fsMant = floor(fMant);
  79.             hiMant = FloatToUnsigned(fsMant);
  80.             fMant = ldexp(fMant - fsMant, 32);
  81.             fsMant = floor(fMant);
  82.             loMant = FloatToUnsigned(fsMant);
  83.         }
  84.     }
  85.  
  86.     /* disable the warning about 'possible loss of data' & 'conversion between
  87.      * diff types' */
  88. #ifdef _MSC_VER
  89. #pragma warning(disable: 4244)
  90. #pragma warning(disable: 4135)
  91. #endif /* Visual C++ */
  92.  
  93.     bytes[0] = (expon >> 8) & 0xff;
  94.     bytes[1] = expon & 0xff;
  95.     bytes[2] = (unsigned char) ((hiMant >> 24) & 0xff);
  96.     bytes[3] = (unsigned char) ((hiMant >> 16) & 0xff);
  97.     bytes[4] = (unsigned char) ((hiMant >> 8) & 0xff);
  98.     bytes[5] = (unsigned char) (hiMant & 0xff);
  99.     bytes[6] = (unsigned char) ((loMant >> 24) & 0xff);
  100.     bytes[7] = (unsigned char) ((loMant >> 16) & 0xff);
  101.     bytes[8] = (unsigned char) ((loMant >> 8) & 0xff);
  102.     bytes[9] = (unsigned char) (loMant & 0xff);
  103.  
  104. #ifdef _MSC_VER
  105. #pragma warning(default: 4244)
  106. #pragma warning(default: 4135)
  107. #endif /* Visual C++ */
  108. }
  109.  
  110. /*
  111.  * C O N V E R T   F R O M     I E E E   E X T E N D E D
  112.  */
  113.  
  114. /*
  115.  * Copyright (C) 1988-1991 Apple Computer, Inc.
  116.  * All rights reserved.
  117.  *
  118.  * Machine-independent I/O routines for IEEE floating-point numbers.
  119.  *
  120.  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  121.  * happens to be infinity on IEEE machines.     Unfortunately, it is
  122.  * impossible to preserve NaN's in a machine-independent way.
  123.  * Infinities are, however, preserved on IEEE machines.
  124.  *
  125.  * These routines have been tested on the following machines:
  126.  *      Apple Macintosh, MPW 3.1 C compiler
  127.  *      Apple Macintosh, THINK C compiler
  128.  *      Silicon Graphics IRIS, MIPS compiler
  129.  *      Cray X/MP and Y/MP
  130.  *      Digital Equipment VAX
  131.  *
  132.  *
  133.  * Implemented by Malcolm Slaney and Ken Turkowski.
  134.  *
  135.  * Malcolm Slaney contributions during 1988-1990 include big- and little-
  136.  * endian file I/O, conversion to and from Motorola's extended 80-bit
  137.  * floating-point format, and conversions to and from IEEE single-
  138.  * precision floating-point format.
  139.  *
  140.  * In 1991, Ken Turkowski implemented the conversions to and from
  141.  * IEEE double-precision format, added more precision to the extended
  142.  * conversions, and accommodated conversions involving +/- infinity,
  143.  * NaN's, and denormalized numbers.
  144.  */
  145.  
  146. #ifndef HUGE_VAL
  147. # define HUGE_VAL HUGE
  148. #endif /*HUGE_VAL*/
  149.  
  150. # define UnsignedToFloat(u) (((double) ((long) (u - 2147483647L - 1))) + 2147483648.0)
  151.  
  152. /****************************************************************
  153.  * Extended precision IEEE floating-point conversion routine.
  154.  ****************************************************************/
  155.  
  156. double ConvertFromIeeeExtended(const unsigned char *bytes)
  157. {
  158.     double            f;
  159.     int                expon;
  160.     unsigned long    hiMant, loMant;
  161.  
  162.     expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
  163.     hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
  164.         | ((unsigned long) (bytes[3] & 0xFF) << 16)
  165.         | ((unsigned long) (bytes[4] & 0xFF) << 8)
  166.         | ((unsigned long) (bytes[5] & 0xFF));
  167.     loMant = ((unsigned long) (bytes[6] & 0xFF) << 24)
  168.         | ((unsigned long) (bytes[7] & 0xFF) << 16)
  169.         | ((unsigned long) (bytes[8] & 0xFF) << 8)
  170.         | ((unsigned long) (bytes[9] & 0xFF));
  171.  
  172.     if (expon == 0 && hiMant == 0 && loMant == 0) {
  173.         f = 0;
  174.     }
  175.     else {
  176.         if (expon == 0x7FFF) {      /* Infinity or NaN */
  177.             f = HUGE_VAL;
  178.         }
  179.         else {
  180.             expon -= 16383;
  181.             f  = ldexp(UnsignedToFloat(hiMant), expon-=31);
  182.             f += ldexp(UnsignedToFloat(loMant), expon-=32);
  183.         }
  184.     }
  185.  
  186.     if (bytes[0] & 0x80)
  187.         return -f;
  188.     else
  189.         return f;
  190. }
  191.  
  192. #endif /* wxUSE_APPLE_IEEE */
  193.