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