Latest OS/2 compiler bug fixes for common and generic
[wxWidgets.git] / src / common / extended.c
1 #if !defined(__VISAGECPP__)
2 # pragma warning(disable:4001) /* non standard extension used: single line comment */
3 #endif
4 #include "wx/setup.h"
5 #include <math.h>
6
7 #if wxUSE_APPLE_IEEE
8
9 /*
10 * C O N V E R T T O I E E E E X T E N D E D
11 */
12
13 /* Copyright (C) 1988-1991 Apple Computer, Inc.
14 * All rights reserved.
15 *
16 * Machine-independent I/O routines for IEEE floating-point numbers.
17 *
18 * NaN's and infinities are converted to HUGE_VAL or HUGE, which
19 * happens to be infinity on IEEE machines. Unfortunately, it is
20 * impossible to preserve NaN's in a machine-independent way.
21 * Infinities are, however, preserved on IEEE machines.
22 *
23 * These routines have been tested on the following machines:
24 * Apple Macintosh, MPW 3.1 C compiler
25 * Apple Macintosh, THINK C compiler
26 * Silicon Graphics IRIS, MIPS compiler
27 * Cray X/MP and Y/MP
28 * Digital Equipment VAX
29 *
30 *
31 * Implemented by Malcolm Slaney and Ken Turkowski.
32 *
33 * Malcolm Slaney contributions during 1988-1990 include big- and little-
34 * endian file I/O, conversion to and from Motorola's extended 80-bit
35 * floating-point format, and conversions to and from IEEE single-
36 * precision floating-point format.
37 *
38 * In 1991, Ken Turkowski implemented the conversions to and from
39 * IEEE double-precision format, added more precision to the extended
40 * conversions, and accommodated conversions involving +/- infinity,
41 * NaN's, and denormalized numbers.
42 */
43
44 #ifndef HUGE_VAL
45 #define HUGE_VAL HUGE
46 #endif /*HUGE_VAL*/
47
48 #define FloatToUnsigned(f) ((unsigned long) (((long) (f - 2147483648.0)) + 2147483647L) + 1)
49
50 void ConvertToIeeeExtended(double num, unsigned char *bytes)
51 {
52 int sign;
53 int expon;
54 double fMant, fsMant;
55 unsigned long hiMant, loMant;
56
57 if (num < 0) {
58 sign = 0x8000;
59 num *= -1;
60 } else {
61 sign = 0;
62 }
63
64 if (num == 0) {
65 expon = 0; hiMant = 0; loMant = 0;
66 }
67 else {
68 fMant = frexp(num, &expon);
69 if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
70 expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
71 }
72 else { /* Finite */
73 expon += 16382;
74 if (expon < 0) { /* denormalized */
75 fMant = ldexp(fMant, expon);
76 expon = 0;
77 }
78 expon |= sign;
79 fMant = ldexp(fMant, 32);
80 fsMant = floor(fMant);
81 hiMant = FloatToUnsigned(fsMant);
82 fMant = ldexp(fMant - fsMant, 32);
83 fsMant = floor(fMant);
84 loMant = FloatToUnsigned(fsMant);
85 }
86 }
87
88 /* disable the warning about 'possible loss of data' & 'conversion between 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 */