]> git.saurik.com Git - wxWidgets.git/blame - src/common/extended.c
tree ctrl sorting shouldn't crash when items don't have data
[wxWidgets.git] / src / common / extended.c
CommitLineData
cf447356
GL
1#include "wx/setup.h"
2#include <math.h>
3
126eb09b 4#if wxUSE_APPLE_IEEE
cf447356
GL
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
47void 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
777553d2 85 /* disable the warning about 'possible loss of data' */
84a19dec
VZ
86 #ifdef _MSC_VER
87 #pragma warning(disable: 4244)
777553d2 88 #endif /* Visual C++ */
84a19dec 89
cf447356
GL
90 bytes[0] = expon >> 8;
91 bytes[1] = expon;
0c32066b
JS
92 bytes[2] = (unsigned char) hiMant >> 24;
93 bytes[3] = (unsigned char) hiMant >> 16;
94 bytes[4] = (unsigned char) hiMant >> 8;
95 bytes[5] = (unsigned char) hiMant;
96 bytes[6] = (unsigned char) loMant >> 24;
97 bytes[7] = (unsigned char) loMant >> 16;
98 bytes[8] = (unsigned char) loMant >> 8;
99 bytes[9] = (unsigned char) loMant;
84a19dec
VZ
100
101 #ifdef _MSC_VER
102 #pragma warning(default: 4244)
777553d2 103 #endif /* Visual C++ */
cf447356
GL
104}
105
106/*
107 * C O N V E R T F R O M I E E E E X T E N D E D
108 */
109
110/*
111 * Copyright (C) 1988-1991 Apple Computer, Inc.
112 * All rights reserved.
113 *
114 * Machine-independent I/O routines for IEEE floating-point numbers.
115 *
116 * NaN's and infinities are converted to HUGE_VAL or HUGE, which
117 * happens to be infinity on IEEE machines. Unfortunately, it is
118 * impossible to preserve NaN's in a machine-independent way.
119 * Infinities are, however, preserved on IEEE machines.
120 *
121 * These routines have been tested on the following machines:
122 * Apple Macintosh, MPW 3.1 C compiler
123 * Apple Macintosh, THINK C compiler
124 * Silicon Graphics IRIS, MIPS compiler
125 * Cray X/MP and Y/MP
126 * Digital Equipment VAX
127 *
128 *
129 * Implemented by Malcolm Slaney and Ken Turkowski.
130 *
131 * Malcolm Slaney contributions during 1988-1990 include big- and little-
132 * endian file I/O, conversion to and from Motorola's extended 80-bit
133 * floating-point format, and conversions to and from IEEE single-
134 * precision floating-point format.
135 *
136 * In 1991, Ken Turkowski implemented the conversions to and from
137 * IEEE double-precision format, added more precision to the extended
138 * conversions, and accommodated conversions involving +/- infinity,
139 * NaN's, and denormalized numbers.
140 */
141
142#ifndef HUGE_VAL
143# define HUGE_VAL HUGE
144#endif /*HUGE_VAL*/
145
146# define UnsignedToFloat(u) (((double) ((long) (u - 2147483647L - 1))) + 2147483648.0)
147
148/****************************************************************
149 * Extended precision IEEE floating-point conversion routine.
150 ****************************************************************/
151
152double ConvertFromIeeeExtended(const unsigned char *bytes)
153{
154 double f;
155 int expon;
156 unsigned long hiMant, loMant;
157
158 expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
159 hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
160 | ((unsigned long) (bytes[3] & 0xFF) << 16)
161 | ((unsigned long) (bytes[4] & 0xFF) << 8)
162 | ((unsigned long) (bytes[5] & 0xFF));
163 loMant = ((unsigned long) (bytes[6] & 0xFF) << 24)
164 | ((unsigned long) (bytes[7] & 0xFF) << 16)
165 | ((unsigned long) (bytes[8] & 0xFF) << 8)
166 | ((unsigned long) (bytes[9] & 0xFF));
167
168 if (expon == 0 && hiMant == 0 && loMant == 0) {
169 f = 0;
170 }
171 else {
172 if (expon == 0x7FFF) { /* Infinity or NaN */
173 f = HUGE_VAL;
174 }
175 else {
176 expon -= 16383;
177 f = ldexp(UnsignedToFloat(hiMant), expon-=31);
178 f += ldexp(UnsignedToFloat(loMant), expon-=32);
179 }
180 }
181
182 if (bytes[0] & 0x80)
183 return -f;
184 else
185 return f;
186}
187
44c4a334 188#endif /* wxUSE_APPLE_IEEE */