]>
git.saurik.com Git - wxWidgets.git/blob - src/common/extended.c
   1 /***************************************************************************** 
   3 ** Purpose:     IEEE Extended<->Double routines to save floats to file 
   4 ** Maintainer:  Ryan Norton 
   8 *****************************************************************************/ 
  11 #if defined(_WIN32_WCE) 
  12     /* eVC cause warnings in its own headers: stdlib.h and winnt.h */ 
  13     #pragma warning (disable:4115) 
  14     #pragma warning (disable:4214) 
  24 #if defined(_WIN32_WCE) 
  25     #pragma warning (default:4115) 
  26     #pragma warning (default:4214) 
  33 /* Copyright (C) 1989-1991 Ken Turkowski. <turk@computer.org> 
  35  * All rights reserved. 
  37  * Warranty Information 
  38  *  Even though I have reviewed this software, I make no warranty 
  39  *  or representation, either express or implied, with respect to this 
  40  *  software, its quality, accuracy, merchantability, or fitness for a 
  41  *  particular purpose.  As a result, this software is provided "as is," 
  42  *  and you, its user, are assuming the entire risk as to its quality 
  45  * This code may be used and freely distributed as long as it includes 
  46  * this copyright notice and the above warranty information. 
  48  * Machine-independent I/O routines for IEEE floating-point numbers. 
  50  * NaN's and infinities are converted to HUGE_VAL or HUGE, which 
  51  * happens to be infinity on IEEE machines.  Unfortunately, it is 
  52  * impossible to preserve NaN's in a machine-independent way. 
  53  * Infinities are, however, preserved on IEEE machines. 
  55  * These routines have been tested on the following machines: 
  56  *    Apple Macintosh, MPW 3.1 C compiler 
  57  *    Apple Macintosh, THINK C compiler 
  58  *    Silicon Graphics IRIS, MIPS compiler 
  60  *    Digital Equipment VAX 
  61  *    Sequent Balance (Multiprocesor 386) 
  65  * Implemented by Malcolm Slaney and Ken Turkowski. 
  67  * Malcolm Slaney contributions during 1988-1990 include big- and little- 
  68  * endian file I/O, conversion to and from Motorola's extended 80-bit 
  69  * floating-point format, and conversions to and from IEEE single- 
  70  * precision floating-point format. 
  72  * In 1991, Ken Turkowski implemented the conversions to and from 
  73  * IEEE double-precision format, added more precision to the extended 
  74  * conversions, and accommodated conversions involving +/- infinity, 
  75  * NaN's, and denormalized numbers. 
  79 # define HUGE_VAL HUGE 
  83 /**************************************************************** 
  84  * The following two routines make up for deficiencies in many 
  85  * compilers to convert properly between unsigned integers and 
  86  * floating-point.  Some compilers which have this bug are the 
  87  * THINK_C compiler for the Macintosh and the C compiler for the 
  88  * Silicon Graphics MIPS-based Iris. 
  89  ****************************************************************/ 
  91 #ifdef applec    /* The Apple C compiler works */ 
  92 # define FloatToUnsigned(f)   ((wxUint32)(f)) 
  93 # define UnsignedToFloat(u)   ((wxFloat64)(u)) 
  95 # define FloatToUnsigned(f)   ((wxUint32)(((wxInt32)((f) - 2147483648.0)) + 2147483647L) + 1) 
  96 # define UnsignedToFloat(u)   (((wxFloat64)((wxInt32)((u) - 2147483647L - 1))) + 2147483648.0) 
 101 /**************************************************************** 
 102  * Extended precision IEEE floating-point conversion routines. 
 103  * Extended is an 80-bit number as defined by Motorola, 
 104  * with a sign bit, 15 bits of exponent (offset 16383?), 
 105  * and a 64-bit mantissa, with no hidden bit. 
 106  ****************************************************************/ 
 108 wxFloat64 
ConvertFromIeeeExtended(const wxInt8 
*bytes
) 
 112     wxUint32 hiMant
, loMant
; 
 114     expon 
= ((bytes
[0] & 0x7F) << 8) | (bytes
[1] & 0xFF); 
 115     hiMant 
= ((wxUint32
)(bytes
[2] & 0xFF) << 24) 
 116             | ((wxUint32
)(bytes
[3] & 0xFF) << 16) 
 117             | ((wxUint32
)(bytes
[4] & 0xFF) << 8) 
 118             | ((wxUint32
)(bytes
[5] & 0xFF)); 
 119     loMant 
= ((wxUint32
)(bytes
[6] & 0xFF) << 24) 
 120             | ((wxUint32
)(bytes
[7] & 0xFF) << 16) 
 121             | ((wxUint32
)(bytes
[8] & 0xFF) << 8) 
 122             | ((wxUint32
)(bytes
[9] & 0xFF)); 
 124     if (expon 
== 0 && hiMant 
== 0 && loMant 
== 0) { 
 128         if (expon 
== 0x7FFF) { /* Infinity or NaN */ 
 133             f  
= ldexp(UnsignedToFloat(hiMant
), expon
-=31); 
 134             f 
+= ldexp(UnsignedToFloat(loMant
), expon
-=32); 
 145 /****************************************************************/ 
 148 void ConvertToIeeeExtended(wxFloat64 num
, wxInt8 
*bytes
) 
 152     wxFloat64 fMant
, fsMant
; 
 153     wxUint32 hiMant
, loMant
; 
 163         expon 
= 0; hiMant 
= 0; loMant 
= 0; 
 166         fMant 
= frexp(num
, &expon
); 
 167         if ((expon 
> 16384) || !(fMant 
< 1)) { /* Infinity or NaN */ 
 168             expon 
= sign
|0x7FFF; hiMant 
= 0; loMant 
= 0; /* infinity */ 
 172             if (expon 
< 0) { /* denormalized */ 
 173                 fMant 
= ldexp(fMant
, expon
); 
 177             fMant 
= ldexp(fMant
, 32);          fsMant 
= floor(fMant
); hiMant 
= FloatToUnsigned(fsMant
); 
 178             fMant 
= ldexp(fMant 
- fsMant
, 32); fsMant 
= floor(fMant
); loMant 
= FloatToUnsigned(fsMant
); 
 182     bytes
[0] = expon 
>> 8; 
 184     bytes
[2] = hiMant 
>> 24; 
 185     bytes
[3] = hiMant 
>> 16; 
 186     bytes
[4] = hiMant 
>> 8; 
 188     bytes
[6] = loMant 
>> 24; 
 189     bytes
[7] = loMant 
>> 16; 
 190     bytes
[8] = loMant 
>> 8; 
 196 #endif /* wxUSE_APPLE_IEEE */