Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/gdtoa/strtordd.c
39475 views
1
/****************************************************************
2
3
The author of this software is David M. Gay.
4
5
Copyright (C) 1998, 2000 by Lucent Technologies
6
All Rights Reserved
7
8
Permission to use, copy, modify, and distribute this software and
9
its documentation for any purpose and without fee is hereby
10
granted, provided that the above copyright notice appear in all
11
copies and that both that the copyright notice and this
12
permission notice and warranty disclaimer appear in supporting
13
documentation, and that the name of Lucent or any of its entities
14
not be used in advertising or publicity pertaining to
15
distribution of the software without specific, written prior
16
permission.
17
18
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25
THIS SOFTWARE.
26
27
****************************************************************/
28
29
/* Please send bug reports to David M. Gay (dmg at acm dot org,
30
* with " at " changed at "@" and " dot " changed to "."). */
31
32
#include "gdtoaimp.h"
33
34
void
35
#ifdef KR_headers
36
ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
37
#else
38
ULtodd(ULong *L, ULong *bits, Long exp, int k)
39
#endif
40
{
41
int i, j;
42
43
switch(k & STRTOG_Retmask) {
44
case STRTOG_NoNumber:
45
case STRTOG_Zero:
46
L[0] = L[1] = L[2] = L[3] = 0;
47
break;
48
49
case STRTOG_Normal:
50
L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
51
L[_0] = (bits[2] >> 21) | (bits[3] << 11 & 0xfffff)
52
| ((exp + 0x3ff + 105) << 20);
53
exp += 0x3ff + 52;
54
if (bits[1] &= 0x1fffff) {
55
i = hi0bits(bits[1]) - 11;
56
if (i >= exp) {
57
i = exp - 1;
58
exp = 0;
59
}
60
else
61
exp -= i;
62
if (i > 0) {
63
bits[1] = bits[1] << i | bits[0] >> (32-i);
64
bits[0] = bits[0] << i & (ULong)0xffffffffL;
65
}
66
}
67
else if (bits[0]) {
68
i = hi0bits(bits[0]) + 21;
69
if (i >= exp) {
70
i = exp - 1;
71
exp = 0;
72
}
73
else
74
exp -= i;
75
if (i < 32) {
76
bits[1] = bits[0] >> (32 - i);
77
bits[0] = bits[0] << i & (ULong)0xffffffffL;
78
}
79
else {
80
bits[1] = bits[0] << (i - 32);
81
bits[0] = 0;
82
}
83
}
84
else {
85
L[2] = L[3] = 0;
86
break;
87
}
88
L[2+_1] = bits[0];
89
L[2+_0] = (bits[1] & 0xfffff) | (exp << 20);
90
break;
91
92
case STRTOG_Denormal:
93
if (bits[3])
94
goto nearly_normal;
95
if (bits[2])
96
goto partly_normal;
97
if (bits[1] & 0xffe00000)
98
goto hardly_normal;
99
/* completely denormal */
100
L[2] = L[3] = 0;
101
L[_1] = bits[0];
102
L[_0] = bits[1];
103
break;
104
105
nearly_normal:
106
i = hi0bits(bits[3]) - 11; /* i >= 12 */
107
j = 32 - i;
108
L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff)
109
| ((65 - i) << 20);
110
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
111
L[2+_0] = bits[1] & (((ULong)1L << j) - 1);
112
L[2+_1] = bits[0];
113
break;
114
115
partly_normal:
116
i = hi0bits(bits[2]) - 11;
117
if (i < 0) {
118
j = -i;
119
i += 32;
120
L[_0] = (bits[2] >> j & 0xfffff) | ((33 + j) << 20);
121
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
122
L[2+_0] = bits[1] & (((ULong)1L << j) - 1);
123
L[2+_1] = bits[0];
124
break;
125
}
126
if (i == 0) {
127
L[_0] = (bits[2] & 0xfffff) | (33 << 20);
128
L[_1] = bits[1];
129
L[2+_0] = 0;
130
L[2+_1] = bits[0];
131
break;
132
}
133
j = 32 - i;
134
L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff)
135
| ((j + 1) << 20);
136
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
137
L[2+_0] = 0;
138
L[2+_1] = bits[0] & ((1L << j) - 1);
139
break;
140
141
hardly_normal:
142
j = 11 - hi0bits(bits[1]);
143
i = 32 - j;
144
L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20);
145
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
146
L[2+_0] = 0;
147
L[2+_1] = bits[0] & (((ULong)1L << j) - 1);
148
break;
149
150
case STRTOG_Infinite:
151
L[_0] = L[2+_0] = 0x7ff00000;
152
L[_1] = L[2+_1] = 0;
153
break;
154
155
case STRTOG_NaN:
156
L[0] = L[2] = d_QNAN0;
157
L[1] = L[3] = d_QNAN1;
158
break;
159
160
case STRTOG_NaNbits:
161
L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
162
L[_0] = bits[2] >> 21 | bits[3] << 11
163
| (ULong)0x7ff00000L;
164
L[2+_1] = bits[0];
165
L[2+_0] = bits[1] | (ULong)0x7ff00000L;
166
}
167
if (k & STRTOG_Neg) {
168
L[_0] |= 0x80000000L;
169
L[2+_0] |= 0x80000000L;
170
}
171
}
172
173
int
174
#ifdef KR_headers
175
strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd;
176
#else
177
strtordd(CONST char *s, char **sp, int rounding, double *dd)
178
#endif
179
{
180
#ifdef Sudden_Underflow
181
static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
182
#else
183
static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
184
#endif
185
FPI *fpi, fpi1;
186
ULong bits[4];
187
Long exp;
188
int k;
189
190
fpi = &fpi0;
191
if (rounding != FPI_Round_near) {
192
fpi1 = fpi0;
193
fpi1.rounding = rounding;
194
fpi = &fpi1;
195
}
196
k = strtodg(s, sp, fpi, &exp, bits);
197
ULtodd((ULong*)dd, bits, exp, k);
198
return k;
199
}
200
201