Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/gdtoa/strtod.c
39475 views
1
/****************************************************************
2
3
The author of this software is David M. Gay.
4
5
Copyright (C) 1998-2001 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
/* $FreeBSD$ */
33
34
#include "gdtoaimp.h"
35
#ifndef NO_FENV_H
36
#include <fenv.h>
37
#endif
38
39
#ifdef USE_LOCALE
40
#include "locale.h"
41
#endif
42
43
#ifdef IEEE_Arith
44
#ifndef NO_IEEE_Scale
45
#define Avoid_Underflow
46
#undef tinytens
47
/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
48
/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
49
static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50
9007199254740992.*9007199254740992.e-256
51
};
52
#endif
53
#endif
54
55
#ifdef Honor_FLT_ROUNDS
56
#undef Check_FLT_ROUNDS
57
#define Check_FLT_ROUNDS
58
#else
59
#define Rounding Flt_Rounds
60
#endif
61
62
#ifdef Avoid_Underflow /*{*/
63
static double
64
sulp
65
#ifdef KR_headers
66
(x, scale) U *x; int scale;
67
#else
68
(U *x, int scale)
69
#endif
70
{
71
U u;
72
double rv;
73
int i;
74
75
rv = ulp(x);
76
if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
77
return rv; /* Is there an example where i <= 0 ? */
78
word0(&u) = Exp_1 + (i << Exp_shift);
79
word1(&u) = 0;
80
return rv * u.d;
81
}
82
#endif /*}*/
83
84
double
85
strtod_l
86
#ifdef KR_headers
87
(s00, se, loc) CONST char *s00; char **se; locale_t loc
88
#else
89
(CONST char *s00, char **se, locale_t loc)
90
#endif
91
{
92
#ifdef Avoid_Underflow
93
int scale;
94
#endif
95
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
96
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
97
CONST char *s, *s0, *s1;
98
double aadj;
99
Long L;
100
U adj, aadj1, rv, rv0;
101
ULong y, z;
102
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
103
#ifdef Avoid_Underflow
104
ULong Lsb, Lsb1;
105
#endif
106
#ifdef SET_INEXACT
107
int inexact, oldinexact;
108
#endif
109
#ifdef USE_LOCALE /*{{*/
110
#ifdef NO_LOCALE_CACHE
111
char *decimalpoint = localeconv_l(loc)->decimal_point;
112
int dplen = strlen(decimalpoint);
113
#else
114
char *decimalpoint;
115
static char *decimalpoint_cache;
116
static int dplen;
117
if (!(s0 = decimalpoint_cache)) {
118
s0 = localeconv_l(loc)->decimal_point;
119
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
120
strcpy(decimalpoint_cache, s0);
121
s0 = decimalpoint_cache;
122
}
123
dplen = strlen(s0);
124
}
125
decimalpoint = (char*)s0;
126
#endif /*NO_LOCALE_CACHE*/
127
#else /*USE_LOCALE}{*/
128
#define dplen 1
129
#endif /*USE_LOCALE}}*/
130
131
#ifdef Honor_FLT_ROUNDS /*{*/
132
int Rounding;
133
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
134
Rounding = Flt_Rounds;
135
#else /*}{*/
136
Rounding = 1;
137
switch(fegetround()) {
138
case FE_TOWARDZERO: Rounding = 0; break;
139
case FE_UPWARD: Rounding = 2; break;
140
case FE_DOWNWARD: Rounding = 3;
141
}
142
#endif /*}}*/
143
#endif /*}*/
144
145
sign = nz0 = nz = decpt = 0;
146
dval(&rv) = 0.;
147
for(s = s00;;s++) switch(*s) {
148
case '-':
149
sign = 1;
150
/* no break */
151
case '+':
152
if (*++s)
153
goto break2;
154
/* no break */
155
case 0:
156
goto ret0;
157
case '\t':
158
case '\n':
159
case '\v':
160
case '\f':
161
case '\r':
162
case ' ':
163
continue;
164
default:
165
goto break2;
166
}
167
break2:
168
if (*s == '0') {
169
#ifndef NO_HEX_FP /*{*/
170
{
171
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
172
Long exp;
173
ULong bits[2];
174
switch(s[1]) {
175
case 'x':
176
case 'X':
177
{
178
#ifdef Honor_FLT_ROUNDS
179
FPI fpi1 = fpi;
180
fpi1.rounding = Rounding;
181
#else
182
#define fpi1 fpi
183
#endif
184
switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
185
case STRTOG_NoNumber:
186
s = s00;
187
sign = 0;
188
case STRTOG_Zero:
189
break;
190
default:
191
if (bb) {
192
copybits(bits, fpi.nbits, bb);
193
Bfree(bb);
194
}
195
ULtod(((U*)&rv)->L, bits, exp, i);
196
}}
197
goto ret;
198
}
199
}
200
#endif /*}*/
201
nz0 = 1;
202
while(*++s == '0') ;
203
if (!*s)
204
goto ret;
205
}
206
s0 = s;
207
y = z = 0;
208
for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
209
if (nd < 9)
210
y = 10*y + c - '0';
211
else if (nd < 16)
212
z = 10*z + c - '0';
213
nd0 = nd;
214
#ifdef USE_LOCALE
215
if (c == *decimalpoint) {
216
for(i = 1; decimalpoint[i]; ++i)
217
if (s[i] != decimalpoint[i])
218
goto dig_done;
219
s += i;
220
c = *s;
221
#else
222
if (c == '.') {
223
c = *++s;
224
#endif
225
decpt = 1;
226
if (!nd) {
227
for(; c == '0'; c = *++s)
228
nz++;
229
if (c > '0' && c <= '9') {
230
s0 = s;
231
nf += nz;
232
nz = 0;
233
goto have_dig;
234
}
235
goto dig_done;
236
}
237
for(; c >= '0' && c <= '9'; c = *++s) {
238
have_dig:
239
nz++;
240
if (c -= '0') {
241
nf += nz;
242
for(i = 1; i < nz; i++)
243
if (nd++ < 9)
244
y *= 10;
245
else if (nd <= DBL_DIG + 1)
246
z *= 10;
247
if (nd++ < 9)
248
y = 10*y + c;
249
else if (nd <= DBL_DIG + 1)
250
z = 10*z + c;
251
nz = 0;
252
}
253
}
254
}/*}*/
255
dig_done:
256
e = 0;
257
if (c == 'e' || c == 'E') {
258
if (!nd && !nz && !nz0) {
259
goto ret0;
260
}
261
s00 = s;
262
esign = 0;
263
switch(c = *++s) {
264
case '-':
265
esign = 1;
266
case '+':
267
c = *++s;
268
}
269
if (c >= '0' && c <= '9') {
270
while(c == '0')
271
c = *++s;
272
if (c > '0' && c <= '9') {
273
L = c - '0';
274
s1 = s;
275
while((c = *++s) >= '0' && c <= '9')
276
L = 10*L + c - '0';
277
if (s - s1 > 8 || L > 19999)
278
/* Avoid confusion from exponents
279
* so large that e might overflow.
280
*/
281
e = 19999; /* safe for 16 bit ints */
282
else
283
e = (int)L;
284
if (esign)
285
e = -e;
286
}
287
else
288
e = 0;
289
}
290
else
291
s = s00;
292
}
293
if (!nd) {
294
if (!nz && !nz0) {
295
#ifdef INFNAN_CHECK
296
/* Check for Nan and Infinity */
297
ULong bits[2];
298
static FPI fpinan = /* only 52 explicit bits */
299
{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
300
if (!decpt)
301
switch(c) {
302
case 'i':
303
case 'I':
304
if (match(&s,"nf")) {
305
--s;
306
if (!match(&s,"inity"))
307
++s;
308
word0(&rv) = 0x7ff00000;
309
word1(&rv) = 0;
310
goto ret;
311
}
312
break;
313
case 'n':
314
case 'N':
315
if (match(&s, "an")) {
316
#ifndef No_Hex_NaN
317
if (*s == '(' /*)*/
318
&& hexnan(&s, &fpinan, bits)
319
== STRTOG_NaNbits) {
320
word0(&rv) = 0x7ff80000 | bits[1];
321
word1(&rv) = bits[0];
322
}
323
else {
324
#endif
325
word0(&rv) = NAN_WORD0;
326
word1(&rv) = NAN_WORD1;
327
#ifndef No_Hex_NaN
328
}
329
#endif
330
goto ret;
331
}
332
}
333
#endif /* INFNAN_CHECK */
334
ret0:
335
s = s00;
336
sign = 0;
337
}
338
goto ret;
339
}
340
e1 = e -= nf;
341
342
/* Now we have nd0 digits, starting at s0, followed by a
343
* decimal point, followed by nd-nd0 digits. The number we're
344
* after is the integer represented by those digits times
345
* 10**e */
346
347
if (!nd0)
348
nd0 = nd;
349
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
350
dval(&rv) = y;
351
if (k > 9) {
352
#ifdef SET_INEXACT
353
if (k > DBL_DIG)
354
oldinexact = get_inexact();
355
#endif
356
dval(&rv) = tens[k - 9] * dval(&rv) + z;
357
}
358
bd0 = 0;
359
if (nd <= DBL_DIG
360
#ifndef RND_PRODQUOT
361
#ifndef Honor_FLT_ROUNDS
362
&& Flt_Rounds == 1
363
#endif
364
#endif
365
) {
366
if (!e)
367
goto ret;
368
#ifndef ROUND_BIASED_without_Round_Up
369
if (e > 0) {
370
if (e <= Ten_pmax) {
371
#ifdef VAX
372
goto vax_ovfl_check;
373
#else
374
#ifdef Honor_FLT_ROUNDS
375
/* round correctly FLT_ROUNDS = 2 or 3 */
376
if (sign) {
377
rv.d = -rv.d;
378
sign = 0;
379
}
380
#endif
381
/* rv = */ rounded_product(dval(&rv), tens[e]);
382
goto ret;
383
#endif
384
}
385
i = DBL_DIG - nd;
386
if (e <= Ten_pmax + i) {
387
/* A fancier test would sometimes let us do
388
* this for larger i values.
389
*/
390
#ifdef Honor_FLT_ROUNDS
391
/* round correctly FLT_ROUNDS = 2 or 3 */
392
if (sign) {
393
rv.d = -rv.d;
394
sign = 0;
395
}
396
#endif
397
e -= i;
398
dval(&rv) *= tens[i];
399
#ifdef VAX
400
/* VAX exponent range is so narrow we must
401
* worry about overflow here...
402
*/
403
vax_ovfl_check:
404
word0(&rv) -= P*Exp_msk1;
405
/* rv = */ rounded_product(dval(&rv), tens[e]);
406
if ((word0(&rv) & Exp_mask)
407
> Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
408
goto ovfl;
409
word0(&rv) += P*Exp_msk1;
410
#else
411
/* rv = */ rounded_product(dval(&rv), tens[e]);
412
#endif
413
goto ret;
414
}
415
}
416
#ifndef Inaccurate_Divide
417
else if (e >= -Ten_pmax) {
418
#ifdef Honor_FLT_ROUNDS
419
/* round correctly FLT_ROUNDS = 2 or 3 */
420
if (sign) {
421
rv.d = -rv.d;
422
sign = 0;
423
}
424
#endif
425
/* rv = */ rounded_quotient(dval(&rv), tens[-e]);
426
goto ret;
427
}
428
#endif
429
#endif /* ROUND_BIASED_without_Round_Up */
430
}
431
e1 += nd - k;
432
433
#ifdef IEEE_Arith
434
#ifdef SET_INEXACT
435
inexact = 1;
436
if (k <= DBL_DIG)
437
oldinexact = get_inexact();
438
#endif
439
#ifdef Avoid_Underflow
440
scale = 0;
441
#endif
442
#ifdef Honor_FLT_ROUNDS
443
if (Rounding >= 2) {
444
if (sign)
445
Rounding = Rounding == 2 ? 0 : 2;
446
else
447
if (Rounding != 2)
448
Rounding = 0;
449
}
450
#endif
451
#endif /*IEEE_Arith*/
452
453
/* Get starting approximation = rv * 10**e1 */
454
455
if (e1 > 0) {
456
if ( (i = e1 & 15) !=0)
457
dval(&rv) *= tens[i];
458
if (e1 &= ~15) {
459
if (e1 > DBL_MAX_10_EXP) {
460
ovfl:
461
/* Can't trust HUGE_VAL */
462
#ifdef IEEE_Arith
463
#ifdef Honor_FLT_ROUNDS
464
switch(Rounding) {
465
case 0: /* toward 0 */
466
case 3: /* toward -infinity */
467
word0(&rv) = Big0;
468
word1(&rv) = Big1;
469
break;
470
default:
471
word0(&rv) = Exp_mask;
472
word1(&rv) = 0;
473
}
474
#else /*Honor_FLT_ROUNDS*/
475
word0(&rv) = Exp_mask;
476
word1(&rv) = 0;
477
#endif /*Honor_FLT_ROUNDS*/
478
#ifdef SET_INEXACT
479
/* set overflow bit */
480
dval(&rv0) = 1e300;
481
dval(&rv0) *= dval(&rv0);
482
#endif
483
#else /*IEEE_Arith*/
484
word0(&rv) = Big0;
485
word1(&rv) = Big1;
486
#endif /*IEEE_Arith*/
487
range_err:
488
if (bd0) {
489
Bfree(bb);
490
Bfree(bd);
491
Bfree(bs);
492
Bfree(bd0);
493
Bfree(delta);
494
}
495
#ifndef NO_ERRNO
496
errno = ERANGE;
497
#endif
498
goto ret;
499
}
500
e1 >>= 4;
501
for(j = 0; e1 > 1; j++, e1 >>= 1)
502
if (e1 & 1)
503
dval(&rv) *= bigtens[j];
504
/* The last multiplication could overflow. */
505
word0(&rv) -= P*Exp_msk1;
506
dval(&rv) *= bigtens[j];
507
if ((z = word0(&rv) & Exp_mask)
508
> Exp_msk1*(DBL_MAX_EXP+Bias-P))
509
goto ovfl;
510
if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
511
/* set to largest number */
512
/* (Can't trust DBL_MAX) */
513
word0(&rv) = Big0;
514
word1(&rv) = Big1;
515
}
516
else
517
word0(&rv) += P*Exp_msk1;
518
}
519
}
520
else if (e1 < 0) {
521
e1 = -e1;
522
if ( (i = e1 & 15) !=0)
523
dval(&rv) /= tens[i];
524
if (e1 >>= 4) {
525
if (e1 >= 1 << n_bigtens)
526
goto undfl;
527
#ifdef Avoid_Underflow
528
if (e1 & Scale_Bit)
529
scale = 2*P;
530
for(j = 0; e1 > 0; j++, e1 >>= 1)
531
if (e1 & 1)
532
dval(&rv) *= tinytens[j];
533
if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
534
>> Exp_shift)) > 0) {
535
/* scaled rv is denormal; zap j low bits */
536
if (j >= 32) {
537
word1(&rv) = 0;
538
if (j >= 53)
539
word0(&rv) = (P+2)*Exp_msk1;
540
else
541
word0(&rv) &= 0xffffffff << (j-32);
542
}
543
else
544
word1(&rv) &= 0xffffffff << j;
545
}
546
#else
547
for(j = 0; e1 > 1; j++, e1 >>= 1)
548
if (e1 & 1)
549
dval(&rv) *= tinytens[j];
550
/* The last multiplication could underflow. */
551
dval(&rv0) = dval(&rv);
552
dval(&rv) *= tinytens[j];
553
if (!dval(&rv)) {
554
dval(&rv) = 2.*dval(&rv0);
555
dval(&rv) *= tinytens[j];
556
#endif
557
if (!dval(&rv)) {
558
undfl:
559
dval(&rv) = 0.;
560
goto range_err;
561
}
562
#ifndef Avoid_Underflow
563
word0(&rv) = Tiny0;
564
word1(&rv) = Tiny1;
565
/* The refinement below will clean
566
* this approximation up.
567
*/
568
}
569
#endif
570
}
571
}
572
573
/* Now the hard part -- adjusting rv to the correct value.*/
574
575
/* Put digits into bd: true value = bd * 10^e */
576
577
bd0 = s2b(s0, nd0, nd, y, dplen);
578
579
for(;;) {
580
bd = Balloc(bd0->k);
581
Bcopy(bd, bd0);
582
bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
583
bs = i2b(1);
584
585
if (e >= 0) {
586
bb2 = bb5 = 0;
587
bd2 = bd5 = e;
588
}
589
else {
590
bb2 = bb5 = -e;
591
bd2 = bd5 = 0;
592
}
593
if (bbe >= 0)
594
bb2 += bbe;
595
else
596
bd2 -= bbe;
597
bs2 = bb2;
598
#ifdef Honor_FLT_ROUNDS
599
if (Rounding != 1)
600
bs2++;
601
#endif
602
#ifdef Avoid_Underflow
603
Lsb = LSB;
604
Lsb1 = 0;
605
j = bbe - scale;
606
i = j + bbbits - 1; /* logb(rv) */
607
j = P + 1 - bbbits;
608
if (i < Emin) { /* denormal */
609
i = Emin - i;
610
j -= i;
611
if (i < 32)
612
Lsb <<= i;
613
else
614
Lsb1 = Lsb << (i-32);
615
}
616
#else /*Avoid_Underflow*/
617
#ifdef Sudden_Underflow
618
#ifdef IBM
619
j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
620
#else
621
j = P + 1 - bbbits;
622
#endif
623
#else /*Sudden_Underflow*/
624
j = bbe;
625
i = j + bbbits - 1; /* logb(&rv) */
626
if (i < Emin) /* denormal */
627
j += P - Emin;
628
else
629
j = P + 1 - bbbits;
630
#endif /*Sudden_Underflow*/
631
#endif /*Avoid_Underflow*/
632
bb2 += j;
633
bd2 += j;
634
#ifdef Avoid_Underflow
635
bd2 += scale;
636
#endif
637
i = bb2 < bd2 ? bb2 : bd2;
638
if (i > bs2)
639
i = bs2;
640
if (i > 0) {
641
bb2 -= i;
642
bd2 -= i;
643
bs2 -= i;
644
}
645
if (bb5 > 0) {
646
bs = pow5mult(bs, bb5);
647
bb1 = mult(bs, bb);
648
Bfree(bb);
649
bb = bb1;
650
}
651
if (bb2 > 0)
652
bb = lshift(bb, bb2);
653
if (bd5 > 0)
654
bd = pow5mult(bd, bd5);
655
if (bd2 > 0)
656
bd = lshift(bd, bd2);
657
if (bs2 > 0)
658
bs = lshift(bs, bs2);
659
delta = diff(bb, bd);
660
dsign = delta->sign;
661
delta->sign = 0;
662
i = cmp(delta, bs);
663
#ifdef Honor_FLT_ROUNDS
664
if (Rounding != 1) {
665
if (i < 0) {
666
/* Error is less than an ulp */
667
if (!delta->x[0] && delta->wds <= 1) {
668
/* exact */
669
#ifdef SET_INEXACT
670
inexact = 0;
671
#endif
672
break;
673
}
674
if (Rounding) {
675
if (dsign) {
676
dval(&adj) = 1.;
677
goto apply_adj;
678
}
679
}
680
else if (!dsign) {
681
dval(&adj) = -1.;
682
if (!word1(&rv)
683
&& !(word0(&rv) & Frac_mask)) {
684
y = word0(&rv) & Exp_mask;
685
#ifdef Avoid_Underflow
686
if (!scale || y > 2*P*Exp_msk1)
687
#else
688
if (y)
689
#endif
690
{
691
delta = lshift(delta,Log2P);
692
if (cmp(delta, bs) <= 0)
693
dval(&adj) = -0.5;
694
}
695
}
696
apply_adj:
697
#ifdef Avoid_Underflow
698
if (scale && (y = word0(&rv) & Exp_mask)
699
<= 2*P*Exp_msk1)
700
word0(&adj) += (2*P+1)*Exp_msk1 - y;
701
#else
702
#ifdef Sudden_Underflow
703
if ((word0(&rv) & Exp_mask) <=
704
P*Exp_msk1) {
705
word0(&rv) += P*Exp_msk1;
706
dval(&rv) += adj*ulp(&rv);
707
word0(&rv) -= P*Exp_msk1;
708
}
709
else
710
#endif /*Sudden_Underflow*/
711
#endif /*Avoid_Underflow*/
712
dval(&rv) += adj.d*ulp(&rv);
713
}
714
break;
715
}
716
dval(&adj) = ratio(delta, bs);
717
if (adj.d < 1.)
718
dval(&adj) = 1.;
719
if (adj.d <= 0x7ffffffe) {
720
/* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
721
y = adj.d;
722
if (y != adj.d) {
723
if (!((Rounding>>1) ^ dsign))
724
y++;
725
dval(&adj) = y;
726
}
727
}
728
#ifdef Avoid_Underflow
729
if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
730
word0(&adj) += (2*P+1)*Exp_msk1 - y;
731
#else
732
#ifdef Sudden_Underflow
733
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
734
word0(&rv) += P*Exp_msk1;
735
dval(&adj) *= ulp(&rv);
736
if (dsign)
737
dval(&rv) += adj;
738
else
739
dval(&rv) -= adj;
740
word0(&rv) -= P*Exp_msk1;
741
goto cont;
742
}
743
#endif /*Sudden_Underflow*/
744
#endif /*Avoid_Underflow*/
745
dval(&adj) *= ulp(&rv);
746
if (dsign) {
747
if (word0(&rv) == Big0 && word1(&rv) == Big1)
748
goto ovfl;
749
dval(&rv) += adj.d;
750
}
751
else
752
dval(&rv) -= adj.d;
753
goto cont;
754
}
755
#endif /*Honor_FLT_ROUNDS*/
756
757
if (i < 0) {
758
/* Error is less than half an ulp -- check for
759
* special case of mantissa a power of two.
760
*/
761
if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
762
#ifdef IEEE_Arith
763
#ifdef Avoid_Underflow
764
|| (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
765
#else
766
|| (word0(&rv) & Exp_mask) <= Exp_msk1
767
#endif
768
#endif
769
) {
770
#ifdef SET_INEXACT
771
if (!delta->x[0] && delta->wds <= 1)
772
inexact = 0;
773
#endif
774
break;
775
}
776
if (!delta->x[0] && delta->wds <= 1) {
777
/* exact result */
778
#ifdef SET_INEXACT
779
inexact = 0;
780
#endif
781
break;
782
}
783
delta = lshift(delta,Log2P);
784
if (cmp(delta, bs) > 0)
785
goto drop_down;
786
break;
787
}
788
if (i == 0) {
789
/* exactly half-way between */
790
if (dsign) {
791
if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
792
&& word1(&rv) == (
793
#ifdef Avoid_Underflow
794
(scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
795
? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
796
#endif
797
0xffffffff)) {
798
/*boundary case -- increment exponent*/
799
if (word0(&rv) == Big0 && word1(&rv) == Big1)
800
goto ovfl;
801
word0(&rv) = (word0(&rv) & Exp_mask)
802
+ Exp_msk1
803
#ifdef IBM
804
| Exp_msk1 >> 4
805
#endif
806
;
807
word1(&rv) = 0;
808
#ifdef Avoid_Underflow
809
dsign = 0;
810
#endif
811
break;
812
}
813
}
814
else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
815
drop_down:
816
/* boundary case -- decrement exponent */
817
#ifdef Sudden_Underflow /*{{*/
818
L = word0(&rv) & Exp_mask;
819
#ifdef IBM
820
if (L < Exp_msk1)
821
#else
822
#ifdef Avoid_Underflow
823
if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
824
#else
825
if (L <= Exp_msk1)
826
#endif /*Avoid_Underflow*/
827
#endif /*IBM*/
828
goto undfl;
829
L -= Exp_msk1;
830
#else /*Sudden_Underflow}{*/
831
#ifdef Avoid_Underflow
832
if (scale) {
833
L = word0(&rv) & Exp_mask;
834
if (L <= (2*P+1)*Exp_msk1) {
835
if (L > (P+2)*Exp_msk1)
836
/* round even ==> */
837
/* accept rv */
838
break;
839
/* rv = smallest denormal */
840
goto undfl;
841
}
842
}
843
#endif /*Avoid_Underflow*/
844
L = (word0(&rv) & Exp_mask) - Exp_msk1;
845
#endif /*Sudden_Underflow}}*/
846
word0(&rv) = L | Bndry_mask1;
847
word1(&rv) = 0xffffffff;
848
#ifdef IBM
849
goto cont;
850
#else
851
break;
852
#endif
853
}
854
#ifndef ROUND_BIASED
855
#ifdef Avoid_Underflow
856
if (Lsb1) {
857
if (!(word0(&rv) & Lsb1))
858
break;
859
}
860
else if (!(word1(&rv) & Lsb))
861
break;
862
#else
863
if (!(word1(&rv) & LSB))
864
break;
865
#endif
866
#endif
867
if (dsign)
868
#ifdef Avoid_Underflow
869
dval(&rv) += sulp(&rv, scale);
870
#else
871
dval(&rv) += ulp(&rv);
872
#endif
873
#ifndef ROUND_BIASED
874
else {
875
#ifdef Avoid_Underflow
876
dval(&rv) -= sulp(&rv, scale);
877
#else
878
dval(&rv) -= ulp(&rv);
879
#endif
880
#ifndef Sudden_Underflow
881
if (!dval(&rv))
882
goto undfl;
883
#endif
884
}
885
#ifdef Avoid_Underflow
886
dsign = 1 - dsign;
887
#endif
888
#endif
889
break;
890
}
891
if ((aadj = ratio(delta, bs)) <= 2.) {
892
if (dsign)
893
aadj = dval(&aadj1) = 1.;
894
else if (word1(&rv) || word0(&rv) & Bndry_mask) {
895
#ifndef Sudden_Underflow
896
if (word1(&rv) == Tiny1 && !word0(&rv))
897
goto undfl;
898
#endif
899
aadj = 1.;
900
dval(&aadj1) = -1.;
901
}
902
else {
903
/* special case -- power of FLT_RADIX to be */
904
/* rounded down... */
905
906
if (aadj < 2./FLT_RADIX)
907
aadj = 1./FLT_RADIX;
908
else
909
aadj *= 0.5;
910
dval(&aadj1) = -aadj;
911
}
912
}
913
else {
914
aadj *= 0.5;
915
dval(&aadj1) = dsign ? aadj : -aadj;
916
#ifdef Check_FLT_ROUNDS
917
switch(Rounding) {
918
case 2: /* towards +infinity */
919
dval(&aadj1) -= 0.5;
920
break;
921
case 0: /* towards 0 */
922
case 3: /* towards -infinity */
923
dval(&aadj1) += 0.5;
924
}
925
#else
926
if (Flt_Rounds == 0)
927
dval(&aadj1) += 0.5;
928
#endif /*Check_FLT_ROUNDS*/
929
}
930
y = word0(&rv) & Exp_mask;
931
932
/* Check for overflow */
933
934
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
935
dval(&rv0) = dval(&rv);
936
word0(&rv) -= P*Exp_msk1;
937
dval(&adj) = dval(&aadj1) * ulp(&rv);
938
dval(&rv) += dval(&adj);
939
if ((word0(&rv) & Exp_mask) >=
940
Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
941
if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
942
goto ovfl;
943
word0(&rv) = Big0;
944
word1(&rv) = Big1;
945
goto cont;
946
}
947
else
948
word0(&rv) += P*Exp_msk1;
949
}
950
else {
951
#ifdef Avoid_Underflow
952
if (scale && y <= 2*P*Exp_msk1) {
953
if (aadj <= 0x7fffffff) {
954
if ((z = aadj) <= 0)
955
z = 1;
956
aadj = z;
957
dval(&aadj1) = dsign ? aadj : -aadj;
958
}
959
word0(&aadj1) += (2*P+1)*Exp_msk1 - y;
960
}
961
dval(&adj) = dval(&aadj1) * ulp(&rv);
962
dval(&rv) += dval(&adj);
963
#else
964
#ifdef Sudden_Underflow
965
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
966
dval(&rv0) = dval(&rv);
967
word0(&rv) += P*Exp_msk1;
968
dval(&adj) = dval(&aadj1) * ulp(&rv);
969
dval(&rv) += adj;
970
#ifdef IBM
971
if ((word0(&rv) & Exp_mask) < P*Exp_msk1)
972
#else
973
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
974
#endif
975
{
976
if (word0(&rv0) == Tiny0
977
&& word1(&rv0) == Tiny1)
978
goto undfl;
979
word0(&rv) = Tiny0;
980
word1(&rv) = Tiny1;
981
goto cont;
982
}
983
else
984
word0(&rv) -= P*Exp_msk1;
985
}
986
else {
987
dval(&adj) = dval(&aadj1) * ulp(&rv);
988
dval(&rv) += adj;
989
}
990
#else /*Sudden_Underflow*/
991
/* Compute dval(&adj) so that the IEEE rounding rules will
992
* correctly round rv + dval(&adj) in some half-way cases.
993
* If rv * ulp(&rv) is denormalized (i.e.,
994
* y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
995
* trouble from bits lost to denormalization;
996
* example: 1.2e-307 .
997
*/
998
if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
999
dval(&aadj1) = (double)(int)(aadj + 0.5);
1000
if (!dsign)
1001
dval(&aadj1) = -dval(&aadj1);
1002
}
1003
dval(&adj) = dval(&aadj1) * ulp(&rv);
1004
dval(&rv) += adj;
1005
#endif /*Sudden_Underflow*/
1006
#endif /*Avoid_Underflow*/
1007
}
1008
z = word0(&rv) & Exp_mask;
1009
#ifndef SET_INEXACT
1010
#ifdef Avoid_Underflow
1011
if (!scale)
1012
#endif
1013
if (y == z) {
1014
/* Can we stop now? */
1015
L = (Long)aadj;
1016
aadj -= L;
1017
/* The tolerances below are conservative. */
1018
if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
1019
if (aadj < .4999999 || aadj > .5000001)
1020
break;
1021
}
1022
else if (aadj < .4999999/FLT_RADIX)
1023
break;
1024
}
1025
#endif
1026
cont:
1027
Bfree(bb);
1028
Bfree(bd);
1029
Bfree(bs);
1030
Bfree(delta);
1031
}
1032
Bfree(bb);
1033
Bfree(bd);
1034
Bfree(bs);
1035
Bfree(bd0);
1036
Bfree(delta);
1037
#ifdef SET_INEXACT
1038
if (inexact) {
1039
if (!oldinexact) {
1040
word0(&rv0) = Exp_1 + (70 << Exp_shift);
1041
word1(&rv0) = 0;
1042
dval(&rv0) += 1.;
1043
}
1044
}
1045
else if (!oldinexact)
1046
clear_inexact();
1047
#endif
1048
#ifdef Avoid_Underflow
1049
if (scale) {
1050
word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
1051
word1(&rv0) = 0;
1052
dval(&rv) *= dval(&rv0);
1053
#ifndef NO_ERRNO
1054
/* try to avoid the bug of testing an 8087 register value */
1055
#ifdef IEEE_Arith
1056
if (!(word0(&rv) & Exp_mask))
1057
#else
1058
if (word0(&rv) == 0 && word1(&rv) == 0)
1059
#endif
1060
errno = ERANGE;
1061
#endif
1062
}
1063
#endif /* Avoid_Underflow */
1064
#ifdef SET_INEXACT
1065
if (inexact && !(word0(&rv) & Exp_mask)) {
1066
/* set underflow bit */
1067
dval(&rv0) = 1e-300;
1068
dval(&rv0) *= dval(&rv0);
1069
}
1070
#endif
1071
ret:
1072
if (se)
1073
*se = (char *)s;
1074
return sign ? -dval(&rv) : dval(&rv);
1075
}
1076
1077
double
1078
strtod
1079
#ifdef KR_headers
1080
(s00, se, loc) CONST char *s00; char **se; locale_t
1081
#else
1082
(CONST char *s00, char **se)
1083
#endif
1084
{
1085
return strtod_l(s00, se, __get_locale());
1086
}
1087
1088
1089