1 /*****************************************************************************
2 ** Name: src/common/extended.c
3 ** Purpose: IEEE Extended<->Double routines to save floats to file
4 ** Maintainer: Ryan Norton
7 *****************************************************************************/
10 #if defined(_WIN32_WCE)
11 /* eVC cause warnings in its own headers: stdlib.h and winnt.h */
12 #pragma warning (disable:4115)
13 #pragma warning (disable:4214)
23 #if defined(_WIN32_WCE)
24 #pragma warning (default:4115)
25 #pragma warning (default:4214)
32 /* Copyright (C) 1989-1991 Ken Turkowski. <turk@computer.org>
34 * All rights reserved.
36 * Warranty Information
37 * Even though I have reviewed this software, I make no warranty
38 * or representation, either express or implied, with respect to this
39 * software, its quality, accuracy, merchantability, or fitness for a
40 * particular purpose. As a result, this software is provided "as is,"
41 * and you, its user, are assuming the entire risk as to its quality
44 * This code may be used and freely distributed as long as it includes
45 * this copyright notice and the above warranty information.
47 * Machine-independent I/O routines for IEEE floating-point numbers.
49 * NaN's and infinities are converted to HUGE_VAL or HUGE, which
50 * happens to be infinity on IEEE machines. Unfortunately, it is
51 * impossible to preserve NaN's in a machine-independent way.
52 * Infinities are, however, preserved on IEEE machines.
54 * These routines have been tested on the following machines:
55 * Apple Macintosh, MPW 3.1 C compiler
56 * Apple Macintosh, THINK C compiler
57 * Silicon Graphics IRIS, MIPS compiler
59 * Digital Equipment VAX
60 * Sequent Balance (Multiprocesor 386)
64 * Implemented by Malcolm Slaney and Ken Turkowski.
66 * Malcolm Slaney contributions during 1988-1990 include big- and little-
67 * endian file I/O, conversion to and from Motorola's extended 80-bit
68 * floating-point format, and conversions to and from IEEE single-
69 * precision floating-point format.
71 * In 1991, Ken Turkowski implemented the conversions to and from
72 * IEEE double-precision format, added more precision to the extended
73 * conversions, and accommodated conversions involving +/- infinity,
74 * NaN's, and denormalized numbers.
78 # define HUGE_VAL HUGE
82 /****************************************************************
83 * The following two routines make up for deficiencies in many
84 * compilers to convert properly between unsigned integers and
85 * floating-point. Some compilers which have this bug are the
86 * THINK_C compiler for the Macintosh and the C compiler for the
87 * Silicon Graphics MIPS-based Iris.
88 ****************************************************************/
90 #ifdef applec /* The Apple C compiler works */
91 # define FloatToUnsigned(f) ((wxUint32)(f))
92 # define UnsignedToFloat(u) ((wxFloat64)(u))
94 # define FloatToUnsigned(f) ((wxUint32)(((wxInt32)((f) - 2147483648.0)) + 2147483647L) + 1)
95 # define UnsignedToFloat(u) (((wxFloat64)((wxInt32)((u) - 2147483647L - 1))) + 2147483648.0)
100 /****************************************************************
101 * Extended precision IEEE floating-point conversion routines.
102 * Extended is an 80-bit number as defined by Motorola,
103 * with a sign bit, 15 bits of exponent (offset 16383?),
104 * and a 64-bit mantissa, with no hidden bit.
105 ****************************************************************/
107 WXDLLIMPEXP_BASE wxFloat64
wxConvertFromIeeeExtended(const wxInt8
*bytes
)
111 wxUint32 hiMant
, loMant
;
113 expon
= ((bytes
[0] & 0x7F) << 8) | (bytes
[1] & 0xFF);
114 hiMant
= ((wxUint32
)(bytes
[2] & 0xFF) << 24)
115 | ((wxUint32
)(bytes
[3] & 0xFF) << 16)
116 | ((wxUint32
)(bytes
[4] & 0xFF) << 8)
117 | ((wxUint32
)(bytes
[5] & 0xFF));
118 loMant
= ((wxUint32
)(bytes
[6] & 0xFF) << 24)
119 | ((wxUint32
)(bytes
[7] & 0xFF) << 16)
120 | ((wxUint32
)(bytes
[8] & 0xFF) << 8)
121 | ((wxUint32
)(bytes
[9] & 0xFF));
123 if (expon
== 0 && hiMant
== 0 && loMant
== 0) {
127 if (expon
== 0x7FFF) { /* Infinity or NaN */
132 f
= ldexp(UnsignedToFloat(hiMant
), expon
-=31);
133 f
+= ldexp(UnsignedToFloat(loMant
), expon
-=32);
144 /****************************************************************/
147 WXDLLIMPEXP_BASE
void wxConvertToIeeeExtended(wxFloat64 num
, wxInt8
*bytes
)
151 wxFloat64 fMant
, fsMant
;
152 wxUint32 hiMant
, loMant
;
162 expon
= 0; hiMant
= 0; loMant
= 0;
165 fMant
= frexp(num
, &expon
);
166 if ((expon
> 16384) || !(fMant
< 1)) { /* Infinity or NaN */
167 expon
= sign
|0x7FFF; hiMant
= 0; loMant
= 0; /* infinity */
171 if (expon
< 0) { /* denormalized */
172 fMant
= ldexp(fMant
, expon
);
176 fMant
= ldexp(fMant
, 32); fsMant
= floor(fMant
); hiMant
= FloatToUnsigned(fsMant
);
177 fMant
= ldexp(fMant
- fsMant
, 32); fsMant
= floor(fMant
); loMant
= FloatToUnsigned(fsMant
);
181 bytes
[0] = expon
>> 8;
183 bytes
[2] = hiMant
>> 24;
184 bytes
[3] = hiMant
>> 16;
185 bytes
[4] = hiMant
>> 8;
187 bytes
[6] = loMant
>> 24;
188 bytes
[7] = loMant
>> 16;
189 bytes
[8] = loMant
>> 8;
193 #if WXWIN_COMPATIBILITY_2_8
194 WXDLLIMPEXP_BASE wxFloat64
ConvertFromIeeeExtended(const wxInt8
*bytes
)
196 return wxConvertFromIeeeExtended(bytes
);
199 WXDLLIMPEXP_BASE
void ConvertToIeeeExtended(wxFloat64 num
, wxInt8
*bytes
)
201 wxConvertToIeeeExtended(num
, bytes
);
203 #endif // WXWIN_COMPATIBILITY_2_8
205 #endif /* wxUSE_APPLE_IEEE */