2 (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 See the copyright notice in the ACK home directory, in the file "Copyright".
8 /* extended precision arithmetic for the strtod() and cvt() routines */
10 /* This may require some more work when long doubles get bigger than 8
11 bytes. In this case, these routines may become obsolete. ???
19 static int b64_add(struct mantissa
*e1
, struct mantissa
*e2
);
20 static b64_sft(struct mantissa
*e1
, int n
);
23 mul_ext(struct EXTEND
*e1
, struct EXTEND
*e2
, struct EXTEND
*e3
)
25 /* Multiply the extended numbers e1 and e2, and put the
28 register int i
,j
; /* loop control */
31 unsigned short result
[8]; /* result */
33 register unsigned short *pres
;
35 /* first save the sign (XOR) */
36 e3
->sign
= e1
->sign
^ e2
->sign
;
38 /* compute new exponent */
39 e3
->exp
= e1
->exp
+ e2
->exp
+ 1;
41 /* check for overflow/underflow ??? */
43 /* 128 bit multiply of mantissas */
45 /* assign unknown long formats */
46 /* to known unsigned word formats */
48 mp
[1] = (unsigned short) e1
->m1
;
50 mp
[3] = (unsigned short) e1
->m2
;
52 mc
[1] = (unsigned short) e2
->m1
;
54 mc
[3] = (unsigned short) e2
->m2
;
59 * fill registers with their components
61 for(i
=4, pres
= &result
[4];i
--;pres
--) if (mp
[i
]) {
63 unsigned long mpi
= mp
[i
];
65 unsigned long tmp
= (unsigned long)pres
[j
] + k
;
66 if (mc
[j
]) tmp
+= mpi
* mc
[j
];
73 if (! (result
[0] & 0x8000)) {
75 for (i
= 0; i
<= 3; i
++) {
77 if (result
[i
+1]&0x8000) result
[i
] |= 1;
82 * combine the registers to a total
84 e3
->m1
= ((unsigned long)(result
[0]) << 16) + result
[1];
85 e3
->m2
= ((unsigned long)(result
[2]) << 16) + result
[3];
86 if (result
[4] & 0x8000) {
97 add_ext(struct EXTEND
*e1
, struct EXTEND
*e2
, struct EXTEND
*e3
)
99 /* Add two extended numbers e1 and e2, and put the result
105 if ((e2
->m1
| e2
->m2
) == 0L) {
109 if ((e1
->m1
| e1
->m2
) == 0L) {
117 /* adjust mantissas to equal power */
118 diff
= e3
->exp
- e1
->exp
;
122 b64_sft(&(e3
->mantissa
), diff
);
126 b64_sft(&(e1
->mantissa
), diff
);
128 if (e1
->sign
!= e3
->sign
) {
129 /* e3 + e1 = e3 - (-e1) */
130 if (e1
->m1
> e3
->m1
||
131 (e1
->m1
== e3
->m1
&& e1
->m2
> e3
->m2
)) {
132 /* abs(e1) > abs(e3) */
133 if (e3
->m2
> e1
->m2
) {
134 e1
->m1
-= 1; /* carry in */
142 e3
->m1
-= 1; /* carry in */
148 if (b64_add(&e3
->mantissa
,&e1
->mantissa
)) {/* addition carry */
149 b64_sft(&e3
->mantissa
,1);/* shift mantissa one bit RIGHT */
150 e3
->m1
|= 0x80000000L
; /* set max bit */
151 e3
->exp
++; /* increase the exponent */
154 if ((e3
->m2
| e3
->m1
) != 0L) {
157 e3
->m1
= e3
->m2
; e3
->m2
= 0L; e3
->exp
-= 32;
159 if (!(e3
->m1
& 0x80000000)) {
160 unsigned long l
= 0x40000000;
163 while (! (l
& e3
->m1
)) {
167 b64_sft(&(e3
->mantissa
), cnt
);
173 cmp_ext(struct EXTEND
*e1
, struct EXTEND
*e2
)
177 e2
->sign
= ! e2
->sign
;
178 add_ext(e1
, e2
, &tmp
);
179 e2
->sign
= ! e2
->sign
;
180 if (tmp
.m1
== 0 && tmp
.m2
== 0) return 0;
181 if (tmp
.sign
) return -1;
186 b64_sft(struct mantissa
*e1
, int n
)
202 e1
->l_32
|= (e1
->h_32
<< (32 - n
));
223 e1
->h_32
|= (e1
->l_32
>> (32 - n
));
231 b64_add(struct mantissa
*e1
, struct mantissa
*e2
)
233 * pointers to 64 bit 'registers'
236 register int overflow
;
239 /* add higher pair of 32 bits */
240 overflow
= ((unsigned long) 0xFFFFFFFF - e1
->h_32
< e2
->h_32
);
241 e1
->h_32
+= e2
->h_32
;
243 /* add lower pair of 32 bits */
244 carry
= ((unsigned long) 0xFFFFFFFF - e1
->l_32
< e2
->l_32
);
245 e1
->l_32
+= e2
->l_32
;
246 if ((carry
) && (++e1
->h_32
== 0))
247 return(1); /* had a 64 bit overflow */
249 return(overflow
); /* return status from higher add */
252 /* The following tables can be computed with the following bc(1)
327 static struct EXTEND ten_powers
[] = { /* representation of 10 ** i */
328 { 0, 0, 0x80000000, 0 },
329 { 0, 3, 0xA0000000, 0 },
330 { 0, 6, 0xC8000000, 0 },
331 { 0, 9, 0xFA000000, 0 },
332 { 0, 13, 0x9C400000, 0 },
333 { 0, 16, 0xC3500000, 0 },
334 { 0, 19, 0xF4240000, 0 },
335 { 0, 23, 0x98968000, 0 },
336 { 0, 26, 0xBEBC2000, 0 },
337 { 0, 29, 0xEE6B2800, 0 },
338 { 0, 33, 0x9502F900, 0 },
339 { 0, 36, 0xBA43B740, 0 },
340 { 0, 39, 0xE8D4A510, 0 },
341 { 0, 43, 0x9184E72A, 0 },
342 { 0, 46, 0xB5E620F4, 0x80000000 },
343 { 0, 49, 0xE35FA931, 0xA0000000 },
344 { 0, 53, 0x8E1BC9BF, 0x04000000 },
345 { 0, 56, 0xB1A2BC2E, 0xC5000000 },
346 { 0, 59, 0xDE0B6B3A, 0x76400000 },
347 { 0, 63, 0x8AC72304, 0x89E80000 },
348 { 0, 66, 0xAD78EBC5, 0xAC620000 },
349 { 0, 69, 0xD8D726B7, 0x177A8000 },
350 { 0, 73, 0x87867832, 0x6EAC9000 },
351 { 0, 76, 0xA968163F, 0x0A57B400 },
352 { 0, 79, 0xD3C21BCE, 0xCCEDA100 },
353 { 0, 83, 0x84595161, 0x401484A0 },
354 { 0, 86, 0xA56FA5B9, 0x9019A5C8 },
355 { 0, 89, 0xCECB8F27, 0xF4200F3A }
357 static struct EXTEND big_ten_powers
[] = { /* representation of 10 ** (28*i) */
358 { 0, 0, 0x80000000, 0 },
359 { 0, 93, 0x813F3978, 0xF8940984 },
360 { 0, 186, 0x82818F12, 0x81ED44A0 },
361 { 0, 279, 0x83C7088E, 0x1AAB65DB },
362 { 0, 372, 0x850FADC0, 0x9923329E },
363 { 0, 465, 0x865B8692, 0x5B9BC5C2 },
364 { 0, 558, 0x87AA9AFF, 0x79042287 },
365 { 0, 651, 0x88FCF317, 0xF22241E2 },
366 { 0, 744, 0x8A5296FF, 0xE33CC930 },
367 { 0, 837, 0x8BAB8EEF, 0xB6409C1A },
368 { 0, 930, 0x8D07E334, 0x55637EB3 },
369 { 0, 1023, 0x8E679C2F, 0x5E44FF8F },
370 { 0, 1116, 0x8FCAC257, 0x558EE4E6 },
371 { 0, 1209, 0x91315E37, 0xDB165AA9 },
372 { 0, 1302, 0x929B7871, 0xDE7F22B9 },
373 { 0, 1395, 0x940919BB, 0xD4620B6D },
374 { 0, 1488, 0x957A4AE1, 0xEBF7F3D4 },
375 { 0, 1581, 0x96EF14C6, 0x454AA840 },
376 { 0, 1674, 0x98678061, 0x27ECE4F5 },
377 { 0, 1767, 0x99E396C1, 0x3A3ACFF2 }
380 static struct EXTEND r_ten_powers
[] = { /* representation of 10 ** -i */
381 { 0, 0, 0x80000000, 0 },
382 { 0, -4, 0xCCCCCCCC, 0xCCCCCCCD },
383 { 0, -7, 0xA3D70A3D, 0x70A3D70A },
384 { 0, -10, 0x83126E97, 0x8D4FDF3B },
385 { 0, -14, 0xD1B71758, 0xE219652C },
386 { 0, -17, 0xA7C5AC47, 0x1B478423 },
387 { 0, -20, 0x8637BD05, 0xAF6C69B6 },
388 { 0, -24, 0xD6BF94D5, 0xE57A42BC },
389 { 0, -27, 0xABCC7711, 0x8461CEFD },
390 { 0, -30, 0x89705F41, 0x36B4A597 },
391 { 0, -34, 0xDBE6FECE, 0xBDEDD5BF },
392 { 0, -37, 0xAFEBFF0B, 0xCB24AAFF },
393 { 0, -40, 0x8CBCCC09, 0x6F5088CC },
394 { 0, -44, 0xE12E1342, 0x4BB40E13 },
395 { 0, -47, 0xB424DC35, 0x095CD80F },
396 { 0, -50, 0x901D7CF7, 0x3AB0ACD9 },
397 { 0, -54, 0xE69594BE, 0xC44DE15B },
398 { 0, -57, 0xB877AA32, 0x36A4B449 },
399 { 0, -60, 0x9392EE8E, 0x921D5D07 },
400 { 0, -64, 0xEC1E4A7D, 0xB69561A5 },
401 { 0, -67, 0xBCE50864, 0x92111AEB },
402 { 0, -70, 0x971DA050, 0x74DA7BEF },
403 { 0, -74, 0xF1C90080, 0xBAF72CB1 },
404 { 0, -77, 0xC16D9A00, 0x95928A27 },
405 { 0, -80, 0x9ABE14CD, 0x44753B53 },
406 { 0, -84, 0xF79687AE, 0xD3EEC551 },
407 { 0, -87, 0xC6120625, 0x76589DDB },
408 { 0, -90, 0x9E74D1B7, 0x91E07E48 }
411 static struct EXTEND r_big_ten_powers
[] = { /* representation of 10 ** -(28*i) */
412 { 0, 0, 0x80000000, 0 },
413 { 0, -94, 0xFD87B5F2, 0x8300CA0E },
414 { 0, -187, 0xFB158592, 0xBE068D2F },
415 { 0, -280, 0xF8A95FCF, 0x88747D94 },
416 { 0, -373, 0xF64335BC, 0xF065D37D },
417 { 0, -466, 0xF3E2F893, 0xDEC3F126 },
418 { 0, -559, 0xF18899B1, 0xBC3F8CA2 },
419 { 0, -652, 0xEF340A98, 0x172AACE5 },
420 { 0, -745, 0xECE53CEC, 0x4A314EBE },
421 { 0, -838, 0xEA9C2277, 0x23EE8BCB },
422 { 0, -931, 0xE858AD24, 0x8F5C22CA },
423 { 0, -1024, 0xE61ACF03, 0x3D1A45DF },
424 { 0, -1117, 0xE3E27A44, 0x4D8D98B8 },
425 { 0, -1210, 0xE1AFA13A, 0xFBD14D6E },
426 { 0, -1303, 0xDF82365C, 0x497B5454 },
427 { 0, -1396, 0xDD5A2C3E, 0xAB3097CC },
428 { 0, -1489, 0xDB377599, 0xB6074245 },
429 { 0, -1582, 0xD91A0545, 0xCDB51186 },
430 { 0, -1675, 0xD701CE3B, 0xD387BF48 },
431 { 0, -1768, 0xD4EEC394, 0xD6258BF8 }
434 #define TP (int)(sizeof(ten_powers)/sizeof(ten_powers[0]))
435 #define BTP (int)(sizeof(big_ten_powers)/sizeof(big_ten_powers[0]))
436 #define MAX_EXP (TP * BTP - 1)
439 add_exponent(struct EXTEND
*e
, int exp
)
449 mul_ext(e
, &r_ten_powers
[modsz
], &x
);
450 mul_ext(&x
, &r_big_ten_powers
[divsz
], e
);
453 mul_ext(e
, &ten_powers
[modsz
], &x
);
454 mul_ext(&x
, &big_ten_powers
[divsz
], e
);
458 _str_ext_cvt(const char *s
, char **ss
, struct EXTEND
*e
)
460 /* Like strtod, but for extended precision */
466 if (ss
) *ss
= (char *)s
;
467 while (isspace(*s
)) s
++;
480 while (c
= *s
++, isdigit(c
) || (c
== '.' && ! dotseen
++)) {
481 if (c
== '.') continue;
483 if (e
->m1
<= (unsigned long)(0xFFFFFFFF)/10) {
487 b64_sft(&(e
->mantissa
), -3);
489 b64_add(&(e
->mantissa
), &a1
);
492 b64_add(&(e
->mantissa
), &a1
);
497 if (! digitseen
) return;
499 if (ss
) *ss
= (char *)s
- 1;
501 if (c
== 'E' || c
== 'e') {
504 int exp_overflow
= 0;
512 if (c
= *s
, isdigit(c
)) {
516 exp1
= 10 * exp1
+ (c
- '0');
517 if ((tmp
= sign
* exp1
+ exp
) > MAX_EXP
||
521 } while (c
= *++s
, isdigit(c
));
522 if (ss
) *ss
= (char *)s
;
526 exp
= sign
* MAX_EXP
;
527 if (e
->m1
!= 0 || e
->m2
!= 0) errno
= ERANGE
;
530 if (e
->m1
== 0 && e
->m2
== 0) return;
532 while (! (e
->m1
& 0x80000000)) {
533 b64_sft(&(e
->mantissa
),-1);
536 add_exponent(e
, exp
);
542 ten_mult(struct EXTEND
*e
)
544 struct EXTEND e1
= *e
;
552 #define NSIGNIFICANT 19
555 _ext_str_cvt(struct EXTEND
*e
, int ndigit
, int *decpt
, int *sign
, int ecvtflag
)
557 /* Like cvt(), but for extended precision */
559 static char buf
[NDIGITS
+1];
561 register char *p
= buf
;
565 if (ndigit
< 0) ndigit
= 0;
566 if (ndigit
> NDIGITS
) ndigit
= NDIGITS
;
578 register struct EXTEND
*pp
= &big_ten_powers
[1];
580 while(cmp_ext(e
,pp
) >= 0) {
582 findex
= pp
- big_ten_powers
;
583 if (findex
>= BTP
) break;
586 findex
= pp
- big_ten_powers
;
587 mul_ext(e
,&r_big_ten_powers
[findex
],e
);
588 *decpt
+= findex
* TP
;
590 while(pp
< &ten_powers
[TP
] && cmp_ext(e
, pp
) >= 0) pp
++;
592 findex
= pp
- ten_powers
;
595 if (cmp_ext(e
, &ten_powers
[0]) < 0) {
596 pp
= &r_big_ten_powers
[1];
597 while(cmp_ext(e
,pp
) < 0) pp
++;
599 findex
= pp
- r_big_ten_powers
;
600 mul_ext(e
, &big_ten_powers
[findex
], e
);
601 *decpt
-= findex
* TP
;
602 /* here, value >= 10 ** -28 */
605 pp
= &r_ten_powers
[0];
606 while(cmp_ext(e
, pp
) < 0) pp
++;
607 findex
= pp
- r_ten_powers
;
608 mul_ext(e
, &ten_powers
[findex
], e
);
612 (*decpt
)++; /* because now value in [1.0, 10.0) */
615 /* for fcvt() we need ndigit digits behind the dot */
617 if (pe
> &buf
[NDIGITS
]) pe
= &buf
[NDIGITS
];
624 struct EXTEND oneminm
;
626 if (p
- pe
> NSIGNIFICANT
) {
631 struct EXTEND tc
, oldtc
;
638 tc
= ten_powers
[findex
];
639 while (cmp_ext(e
, &tc
) >= 0) {
641 add_ext(&tc
, &ten_powers
[findex
], &tc
);
646 add_ext(e
, &oldtc
, e
);
652 add_ext(&ten_powers
[0], &m
, &oneminm
);
657 x
.m2
= 0; x
.exp
= e
->exp
;
659 x
.m1
= e
->m1
>>(31-e
->exp
);
661 x
.m1
= x
.m1
<< (31-e
->exp
);
665 /* Check that remainder is still significant */
666 if (cmp_ext(&m
, e
) > 0 || cmp_ext(e
, &oneminm
) > 0) {
667 if (e
->m1
&& e
->exp
>= -1) *(p
-1) += 1;
678 *p
+= 5; /* round of at the end */
686 /* maybe add another digit at the end,
687 because the point was shifted right
689 if (pe
> buf
) *pe
= '0';
699 _dbl_ext_cvt(double value
, struct EXTEND
*e
)
701 /* Convert double to extended
705 value
= frexp(value
, &exponent
);
706 e
->sign
= value
< 0.0;
707 if (e
->sign
) value
= -value
;
708 e
->exp
= exponent
- 1;
709 value
*= 4294967296.0;
712 value
*= 4294967296.0;
716 static struct EXTEND max_d
;
719 _ext_dbl_cvt(struct EXTEND
*e
)
721 /* Convert extended to double
727 if (e
->m1
== 0 && e
->m2
== 0) {
730 if (max_d
.exp
== 0) {
731 _dbl_ext_cvt(DBL_MAX
, &max_d
);
733 if (cmp_ext(&max_d
, e
) < 0) {
737 else f
= ldexp((double)e
->m1
*4294967296.0 + (double)e
->m2
, e
->exp
-63);
739 if (f
== 0.0 && (e
->m1
!= 0 || e
->m2
!= 0)) {