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