1 /****************************************************************
3 The author of this software is David M. Gay.
5 Copyright (C) 1998, 1999 by Lucent Technologies
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
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
27 ****************************************************************/
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
34 static Bigint
*freelist
[Kmax
+1];
35 #ifndef Omit_Private_Memory
37 #define PRIVATE_MEM 2304
39 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
40 static double private_mem
[PRIVATE_mem
], *pmem_next
= private_mem
;
53 #ifndef Omit_Private_Memory
58 if ( (rv
= freelist
[k
]) !=0) {
59 freelist
[k
] = rv
->next
;
63 #ifdef Omit_Private_Memory
64 rv
= (Bigint
*)MALLOC(sizeof(Bigint
) + (x
-1)*sizeof(ULong
));
66 len
= (sizeof(Bigint
) + (x
-1)*sizeof(ULong
) + sizeof(double) - 1)
68 if (pmem_next
- private_mem
+ len
<= PRIVATE_mem
) {
69 rv
= (Bigint
*)pmem_next
;
73 rv
= (Bigint
*)MALLOC(len
*sizeof(double));
79 rv
->sign
= rv
->wds
= 0;
93 v
->next
= freelist
[v
->k
];
108 register ULong x
= *y
;
150 (b
, m
, a
) Bigint
*b
; int m
, a
;
152 (Bigint
*b
, int m
, int a
) /* multiply by m and add a */
173 y
= *x
* (ULLong
)m
+ carry
;
175 *x
++ = y
& 0xffffffffUL
;
179 y
= (xi
& 0xffff) * m
+ carry
;
180 z
= (xi
>> 16) * m
+ (y
>> 16);
182 *x
++ = (z
<< 16) + (y
& 0xffff);
192 if (wds
>= b
->maxwds
) {
207 (x
) register ULong x
;
214 if (!(x
& 0xffff0000)) {
218 if (!(x
& 0xff000000)) {
222 if (!(x
& 0xf0000000)) {
226 if (!(x
& 0xc0000000)) {
230 if (!(x
& 0x80000000)) {
232 if (!(x
& 0x40000000))
257 (a
, b
) Bigint
*a
, *b
;
259 (Bigint
*a
, Bigint
*b
)
264 ULong
*x
, *xa
, *xae
, *xb
, *xbe
, *xc
, *xc0
;
275 if (a
->wds
< b
->wds
) {
287 for(x
= c
->x
, xa
= x
+ wc
; x
< xa
; x
++)
295 for(; xb
< xbe
; xc0
++) {
296 if ( (y
= *xb
++) !=0) {
301 z
= *x
++ * (ULLong
)y
+ *xc
+ carry
;
303 *xc
++ = z
& 0xffffffffUL
;
311 for(; xb
< xbe
; xb
++, xc0
++) {
312 if ( (y
= *xb
& 0xffff) !=0) {
317 z
= (*x
& 0xffff) * y
+ (*xc
& 0xffff) + carry
;
319 z2
= (*x
++ >> 16) * y
+ (*xc
>> 16) + carry
;
326 if ( (y
= *xb
>> 16) !=0) {
332 z
= (*x
& 0xffff) * y
+ (*xc
>> 16) + carry
;
335 z2
= (*x
++ >> 16) * y
+ (*xc
& 0xffff) + carry
;
343 for(; xb
< xbe
; xc0
++) {
344 if ( (y
= *xb
++) !=0) {
349 z
= *x
++ * y
+ *xc
+ carry
;
359 for(xc0
= c
->x
, xc
= xc0
+ wc
; wc
> 0 && !*--xc
; --wc
) ;
369 (b
, k
) Bigint
*b
; int k
;
374 Bigint
*b1
, *p5
, *p51
;
376 static int p05
[3] = { 5, 25, 125 };
378 if ( (i
= k
& 3) !=0)
379 b
= multadd(b
, p05
[i
-1], 0);
383 if ((p5
= p5s
) == 0) {
385 #ifdef MULTIPLE_THREADS
386 ACQUIRE_DTOA_LOCK(1);
405 if ((p51
= p5
->next
) == 0) {
406 #ifdef MULTIPLE_THREADS
407 ACQUIRE_DTOA_LOCK(1);
408 if (!(p51
= p5
->next
)) {
409 p51
= p5
->next
= mult(p5
,p5
);
414 p51
= p5
->next
= mult(p5
,p5
);
426 (b
, k
) Bigint
*b
; int k
;
433 ULong
*x
, *x1
, *xe
, z
;
438 for(i
= b
->maxwds
; n1
> i
; i
<<= 1)
442 for(i
= 0; i
< n
; i
++)
461 *x1
++ = *x
<< k
& 0xffff | z
;
480 (a
, b
) Bigint
*a
, *b
;
482 (Bigint
*a
, Bigint
*b
)
485 ULong
*xa
, *xa0
, *xb
, *xb0
;
491 if (i
> 1 && !a
->x
[i
-1])
492 Bug("cmp called with a->x[a->wds-1] == 0");
493 if (j
> 1 && !b
->x
[j
-1])
494 Bug("cmp called with b->x[b->wds-1] == 0");
504 return *xa
< *xb
? -1 : 1;
514 (a
, b
) Bigint
*a
, *b
;
516 (Bigint
*a
, Bigint
*b
)
521 ULong
*xa
, *xae
, *xb
, *xbe
, *xc
;
558 y
= (ULLong
)*xa
++ - *xb
++ - borrow
;
559 borrow
= y
>> 32 & 1UL;
560 *xc
++ = y
& 0xffffffffUL
;
565 borrow
= y
>> 32 & 1UL;
566 *xc
++ = y
& 0xffffffffUL
;
571 y
= (*xa
& 0xffff) - (*xb
& 0xffff) - borrow
;
572 borrow
= (y
& 0x10000) >> 16;
573 z
= (*xa
++ >> 16) - (*xb
++ >> 16) - borrow
;
574 borrow
= (z
& 0x10000) >> 16;
579 y
= (*xa
& 0xffff) - borrow
;
580 borrow
= (y
& 0x10000) >> 16;
581 z
= (*xa
++ >> 16) - borrow
;
582 borrow
= (z
& 0x10000) >> 16;
587 y
= *xa
++ - *xb
++ - borrow
;
588 borrow
= (y
& 0x10000) >> 16;
594 borrow
= (y
& 0x10000) >> 16;
608 (a
, e
) Bigint
*a
; int *e
;
613 ULong
*xa
, *xa0
, w
, y
, z
;
627 if (!y
) Bug("zero y in b2d");
633 d0
= Exp_1
| y
>> Ebits
- k
;
634 w
= xa
> xa0
? *--xa
: 0;
635 d1
= y
<< (32-Ebits
) + k
| w
>> Ebits
- k
;
638 z
= xa
> xa0
? *--xa
: 0;
640 d0
= Exp_1
| y
<< k
| z
>> 32 - k
;
641 y
= xa
> xa0
? *--xa
: 0;
642 d1
= z
<< k
| y
>> 32 - k
;
649 if (k
< Ebits
+ 16) {
650 z
= xa
> xa0
? *--xa
: 0;
651 d0
= Exp_1
| y
<< k
- Ebits
| z
>> Ebits
+ 16 - k
;
652 w
= xa
> xa0
? *--xa
: 0;
653 y
= xa
> xa0
? *--xa
: 0;
654 d1
= z
<< k
+ 16 - Ebits
| w
<< k
- Ebits
| y
>> 16 + Ebits
- k
;
657 z
= xa
> xa0
? *--xa
: 0;
658 w
= xa
> xa0
? *--xa
: 0;
660 d0
= Exp_1
| y
<< k
+ 16 | z
<< k
| w
>> 16 - k
;
661 y
= xa
> xa0
? *--xa
: 0;
662 d1
= w
<< k
+ 16 | y
<< k
;
666 word0(d
) = d0
>> 16 | d0
<< 16;
667 word1(d
) = d1
>> 16 | d1
<< 16;
677 (d
, e
, bits
) double d
; int *e
, *bits
;
679 (double d
, int *e
, int *bits
)
683 #ifndef Sudden_Underflow
690 d0
= word0(d
) >> 16 | word0(d
) << 16;
691 d1
= word1(d
) >> 16 | word1(d
) << 16;
705 d0
&= 0x7fffffff; /* clear sign bit, which we ignore */
706 #ifdef Sudden_Underflow
707 de
= (int)(d0
>> Exp_shift
);
712 if ( (de
= (int)(d0
>> Exp_shift
)) !=0)
717 if ( (k
= lo0bits(&y
)) !=0) {
718 x
[0] = y
| z
<< 32 - k
;
723 #ifndef Sudden_Underflow
726 b
->wds
= (x
[1] = z
) !=0 ? 2 : 1;
731 Bug("Zero passed to d2b");
735 #ifndef Sudden_Underflow
743 if ( (k
= lo0bits(&y
)) !=0)
745 x
[0] = y
| z
<< 32 - k
& 0xffff;
746 x
[1] = z
>> k
- 16 & 0xffff;
752 x
[1] = y
>> 16 | z
<< 16 - k
& 0xffff;
753 x
[2] = z
>> k
& 0xffff;
768 Bug("Zero passed to d2b");
786 #ifndef Sudden_Underflow
790 *e
= (de
- Bias
- (P
-1) << 2) + k
;
791 *bits
= 4*P
+ 8 - k
- hi0bits(word0(d
) & Frac_mask
);
793 *e
= de
- Bias
- (P
-1) + k
;
796 #ifndef Sudden_Underflow
799 *e
= de
- Bias
- (P
-1) + 1 + k
;
801 *bits
= 32*i
- hi0bits(x
[i
-1]);
803 *bits
= (i
+2)*16 - hi0bits(x
[i
]);
814 bigtens
[] = { 1e16
, 1e32
, 1e64
, 1e128
, 1e256
};
815 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
819 bigtens
[] = { 1e16
, 1e32
, 1e64
};
820 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64 };
822 bigtens
[] = { 1e16
, 1e32
};
823 CONST
double tinytens
[] = { 1e-16, 1e-32 };
829 1e0
, 1e1
, 1e2
, 1e3
, 1e4
, 1e5
, 1e6
, 1e7
, 1e8
, 1e9
,
830 1e10
, 1e11
, 1e12
, 1e13
, 1e14
, 1e15
, 1e16
, 1e17
, 1e18
, 1e19
,
839 strcp_D2A(a
, b
) char *a
; char *b
;
841 strcp_D2A(char *a
, CONST
char *b
)
853 memcpy_D2A(a
, b
, len
) Char
*a
; Char
*b
; size_t len
;
855 memcpy_D2A(void *a1
, void *b1
, size_t len
)
858 register char *a
= (char*)a1
, *ae
= a
+ len
;
859 register char *b
= (char*)b1
, *a0
= a
;
865 #endif /* NO_STRING_H */