]>
Commit | Line | Data |
---|---|---|
34e8f829 A |
1 | --- gdtoa-strtopdd.c.orig 2008-10-28 12:43:22.000000000 -0700 |
2 | +++ gdtoa-strtopdd.c 2008-10-28 12:51:49.000000000 -0700 | |
3 | @@ -29,13 +29,25 @@ THIS SOFTWARE. | |
3d9156a7 A |
4 | /* Please send bug reports to David M. Gay (dmg at acm dot org, |
5 | * with " at " changed at "@" and " dot " changed to "."). */ | |
6 | ||
7 | +#include "xlocale_private.h" | |
8 | + | |
9 | #include "gdtoaimp.h" | |
10 | ||
11 | +#ifdef __APPLE__ | |
12 | +/* | |
13 | + * IEEE specifies that the most significant (head) double is required to | |
14 | + * be equal to the long double rounded to the nearest double, so that means | |
15 | + * the tail double might be the opposite sign as the head. We can do this | |
16 | + * adding (long double)0 to the number, which will fix it up. | |
17 | + */ | |
18 | +#define fixLDBL(x) ((x) += 0.L) | |
19 | +#endif /* __APPLE__ */ | |
20 | + | |
21 | int | |
22 | #ifdef KR_headers | |
23 | -strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; | |
34e8f829 | 24 | +strtopdd(s, sp, dd, loc) CONST char *s; char **sp; double *dd; locale_t loc; |
3d9156a7 A |
25 | #else |
26 | -strtopdd(CONST char *s, char **sp, double *dd) | |
27 | +strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) | |
28 | #endif | |
29 | { | |
30 | #ifdef Sudden_Underflow | |
34e8f829 | 31 | @@ -49,6 +61,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
32 | typedef union { |
33 | double d[2]; | |
34 | ULong L[4]; | |
35 | +#ifdef __APPLE__ | |
36 | + long double ld; | |
37 | +#endif /* __APPLE__ */ | |
38 | } U; | |
39 | U *u; | |
34e8f829 A |
40 | #ifdef Honor_FLT_ROUNDS |
41 | @@ -57,10 +72,13 @@ strtopdd(CONST char *s, char **sp, doubl | |
42 | #define fpi &fpi0 | |
43 | #endif | |
3d9156a7 | 44 | |
34e8f829 | 45 | - rv = strtodg(s, sp, fpi, &exp, bits); |
224c7076 | 46 | + rv = strtodg(s, sp, fpi, &exp, bits, loc); |
3d9156a7 A |
47 | u = (U*)dd; |
48 | switch(rv & STRTOG_Retmask) { | |
49 | case STRTOG_NoNumber: | |
224c7076 A |
50 | + u->d[0] = u->d[1] = 0.; |
51 | + return rv; // avoid setting sign | |
52 | + | |
53 | case STRTOG_Zero: | |
54 | u->d[0] = u->d[1] = 0.; | |
55 | break; | |
34e8f829 | 56 | @@ -106,6 +124,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
57 | } |
58 | u->L[2+_1] = bits[0]; | |
59 | u->L[2+_0] = bits[1] & 0xfffff | exp << 20; | |
60 | +#ifdef __APPLE__ | |
61 | + fixLDBL(u->ld); | |
62 | +#endif /* __APPLE__ */ | |
63 | break; | |
64 | ||
65 | case STRTOG_Denormal: | |
34e8f829 | 66 | @@ -129,6 +150,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
67 | u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; |
68 | u->L[2+_0] = bits[1] & (1L << j) - 1; | |
69 | u->L[2+_1] = bits[0]; | |
70 | +#ifdef __APPLE__ | |
71 | + fixLDBL(u->ld); | |
72 | +#endif /* __APPLE__ */ | |
73 | break; | |
74 | ||
75 | partly_normal: | |
34e8f829 | 76 | @@ -140,6 +164,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
77 | u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; |
78 | u->L[2+_0] = bits[1] & (1L << j) - 1; | |
79 | u->L[2+_1] = bits[0]; | |
80 | +#ifdef __APPLE__ | |
81 | + fixLDBL(u->ld); | |
82 | +#endif /* __APPLE__ */ | |
83 | break; | |
84 | } | |
85 | if (i == 0) { | |
34e8f829 | 86 | @@ -147,6 +174,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
87 | u->L[_1] = bits[1]; |
88 | u->L[2+_0] = 0; | |
89 | u->L[2+_1] = bits[0]; | |
90 | +#ifdef __APPLE__ | |
91 | + fixLDBL(u->ld); | |
92 | +#endif /* __APPLE__ */ | |
93 | break; | |
94 | } | |
95 | j = 32 - i; | |
34e8f829 | 96 | @@ -155,6 +185,9 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
97 | u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; |
98 | u->L[2+_0] = 0; | |
99 | u->L[2+_1] = bits[0] & (1L << j) - 1; | |
100 | +#ifdef __APPLE__ | |
101 | + fixLDBL(u->ld); | |
102 | +#endif /* __APPLE__ */ | |
103 | break; | |
104 | ||
105 | hardly_normal: | |
34e8f829 | 106 | @@ -164,20 +197,45 @@ strtopdd(CONST char *s, char **sp, doubl |
3d9156a7 A |
107 | u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; |
108 | u->L[2+_0] = 0; | |
109 | u->L[2+_1] = bits[0] & (1L << j) - 1; | |
110 | +#ifdef __APPLE__ | |
111 | + fixLDBL(u->ld); | |
112 | +#endif /* __APPLE__ */ | |
113 | break; | |
114 | ||
115 | case STRTOG_Infinite: | |
116 | +#ifdef __APPLE__ | |
117 | + u->L[_0] = 0x7ff00000; | |
118 | + u->L[_1] = u->L[2+_0] = u->L[2+_1] = 0; | |
119 | +#else /* __APPLE__ */ | |
120 | u->L[_0] = u->L[2+_0] = 0x7ff00000; | |
121 | u->L[_1] = u->L[2+_1] = 0; | |
122 | +#endif /* __APPLE__ */ | |
123 | break; | |
124 | ||
125 | case STRTOG_NaN: | |
126 | +#ifdef __APPLE__ | |
224c7076 A |
127 | + u->L[0] = d_QNAN0; |
128 | + u->L[1] = d_QNAN1; | |
129 | + u->L[2] = u->L[3] = 0; | |
3d9156a7 A |
130 | +#else /* __APPLE__ */ |
131 | u->L[0] = u->L[2] = d_QNAN0; | |
132 | u->L[1] = u->L[3] = d_QNAN1; | |
224c7076 | 133 | +#endif /* __APPLE__ */ |
34e8f829 | 134 | + break; |
224c7076 A |
135 | +#ifdef __APPLE__ |
136 | + case STRTOG_NaNbits: | |
137 | + u->L[0] = d_QNAN0 | ((bits[2] >> 20 | bits[3] << 12) & 0xfffff); | |
138 | + u->L[1] = d_QNAN1 | bits[1] >> 20 | bits[2] << 12; | |
139 | + u->L[2] = u->L[3] = 0; | |
3d9156a7 A |
140 | +#endif /* __APPLE__ */ |
141 | } | |
142 | if (rv & STRTOG_Neg) { | |
143 | u->L[ _0] |= 0x80000000L; | |
144 | +#ifdef __APPLE__ | |
145 | + u->L[2+_0] ^= 0x80000000L; | |
146 | +#else /* __APPLE__ */ | |
147 | u->L[2+_0] |= 0x80000000L; | |
148 | +#endif /* __APPLE__ */ | |
149 | } | |
150 | return rv; | |
151 | } |