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 "."). */
33 #define Omit_Private_Memory
37 #endif /* GDTOA_TSD */
41 static pthread_key_t gdtoa_tsd_key
= (pthread_key_t
)-1;
42 static pthread_mutex_t gdtoa_tsd_lock
= PTHREAD_MUTEX_INITIALIZER
;
43 #else /* !GDTOA_TSD */
44 static Bigint
*freelist
[Kmax
+1];
45 #endif /* GDTOA_TSD */
46 #ifndef Omit_Private_Memory
48 #define PRIVATE_MEM 2304
50 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
51 static double private_mem
[PRIVATE_mem
], *pmem_next
= private_mem
;
56 gdtoa_freelist_free(void *x
)
60 Bigint
**fl
= (Bigint
**)x
;
63 for(i
= 0; i
< Kmax
+1; fl
++, i
++) {
65 for(cur
= *fl
; cur
; cur
= next
) {
72 #endif /* GDTOA_TSD */
84 #ifndef Omit_Private_Memory
90 if (gdtoa_tsd_key
== (pthread_key_t
)-1) {
91 pthread_mutex_lock(&gdtoa_tsd_lock
);
92 if (gdtoa_tsd_key
== (pthread_key_t
)-1) {
93 gdtoa_tsd_key
= __LIBC_PTHREAD_KEY_GDTOA_BIGINT
;
94 pthread_key_init_np(gdtoa_tsd_key
, gdtoa_freelist_free
);
96 pthread_mutex_unlock(&gdtoa_tsd_lock
);
98 if ((freelist
= (Bigint
**)pthread_getspecific(gdtoa_tsd_key
)) == NULL
) {
99 freelist
= (Bigint
**)MALLOC((Kmax
+1) * sizeof(Bigint
*));
100 bzero(freelist
, (Kmax
+1) * sizeof(Bigint
*));
101 pthread_setspecific(gdtoa_tsd_key
, freelist
);
103 #else /* !GDTOA_TSD */
104 ACQUIRE_DTOA_LOCK(0);
105 #endif /* GDTOA_TSD */
106 /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
107 /* but this case seems very unlikely. */
108 if (k
<= Kmax
&& (rv
= freelist
[k
]) !=0) {
109 freelist
[k
] = rv
->next
;
113 #ifdef Omit_Private_Memory
114 rv
= (Bigint
*)MALLOC(sizeof(Bigint
) + (x
-1)*sizeof(ULong
));
116 len
= (sizeof(Bigint
) + (x
-1)*sizeof(ULong
) + sizeof(double) - 1)
118 if (k
<= Kmax
&& pmem_next
- private_mem
+ len
<= PRIVATE_mem
) {
119 rv
= (Bigint
*)pmem_next
;
123 rv
= (Bigint
*)MALLOC(len
*sizeof(double));
130 #endif /* GDTOA_TSD */
131 rv
->sign
= rv
->wds
= 0;
152 Bigint
**freelist
= (Bigint
**)pthread_getspecific(gdtoa_tsd_key
);
153 #else /* !GDTOA_TSD */
154 ACQUIRE_DTOA_LOCK(0);
155 #endif /* !GDTOA_TSD */
156 v
->next
= freelist
[v
->k
];
160 #endif /* !GDTOA_TSD */
216 (b
, m
, a
) Bigint
*b
; int m
, a
;
218 (Bigint
*b
, int m
, int a
) /* multiply by m and add a */
239 y
= *x
* (ULLong
)m
+ carry
;
241 *x
++ = y
& 0xffffffffUL
;
245 y
= (xi
& 0xffff) * m
+ carry
;
246 z
= (xi
>> 16) * m
+ (y
>> 16);
248 *x
++ = (z
<< 16) + (y
& 0xffff);
258 if (wds
>= b
->maxwds
) {
280 if (!(x
& 0xffff0000)) {
284 if (!(x
& 0xff000000)) {
288 if (!(x
& 0xf0000000)) {
292 if (!(x
& 0xc0000000)) {
296 if (!(x
& 0x80000000)) {
298 if (!(x
& 0x40000000))
323 (a
, b
) Bigint
*a
, *b
;
325 (Bigint
*a
, Bigint
*b
)
330 ULong
*x
, *xa
, *xae
, *xb
, *xbe
, *xc
, *xc0
;
341 if (a
->wds
< b
->wds
) {
353 for(x
= c
->x
, xa
= x
+ wc
; x
< xa
; x
++)
361 for(; xb
< xbe
; xc0
++) {
362 if ( (y
= *xb
++) !=0) {
367 z
= *x
++ * (ULLong
)y
+ *xc
+ carry
;
369 *xc
++ = z
& 0xffffffffUL
;
377 for(; xb
< xbe
; xb
++, xc0
++) {
378 if ( (y
= *xb
& 0xffff) !=0) {
383 z
= (*x
& 0xffff) * y
+ (*xc
& 0xffff) + carry
;
385 z2
= (*x
++ >> 16) * y
+ (*xc
>> 16) + carry
;
392 if ( (y
= *xb
>> 16) !=0) {
398 z
= (*x
& 0xffff) * y
+ (*xc
>> 16) + carry
;
401 z2
= (*x
++ >> 16) * y
+ (*xc
& 0xffff) + carry
;
409 for(; xb
< xbe
; xc0
++) {
410 if ( (y
= *xb
++) !=0) {
415 z
= *x
++ * y
+ *xc
+ carry
;
425 for(xc0
= c
->x
, xc
= xc0
+ wc
; wc
> 0 && !*--xc
; --wc
) ;
435 (b
, k
) Bigint
*b
; int k
;
440 Bigint
*b1
, *p5
, *p51
;
442 static int p05
[3] = { 5, 25, 125 };
444 if ( (i
= k
& 3) !=0)
445 b
= multadd(b
, p05
[i
-1], 0);
449 if ((p5
= p5s
) == 0) {
451 #ifdef MULTIPLE_THREADS
452 ACQUIRE_DTOA_LOCK(1);
471 if ((p51
= p5
->next
) == 0) {
472 #ifdef MULTIPLE_THREADS
473 ACQUIRE_DTOA_LOCK(1);
474 if (!(p51
= p5
->next
)) {
475 p51
= p5
->next
= mult(p5
,p5
);
480 p51
= p5
->next
= mult(p5
,p5
);
492 (b
, k
) Bigint
*b
; int k
;
499 ULong
*x
, *x1
, *xe
, z
;
504 for(i
= b
->maxwds
; n1
> i
; i
<<= 1)
508 for(i
= 0; i
< n
; i
++)
527 *x1
++ = *x
<< k
& 0xffff | z
;
546 (a
, b
) Bigint
*a
, *b
;
548 (Bigint
*a
, Bigint
*b
)
551 ULong
*xa
, *xa0
, *xb
, *xb0
;
557 if (i
> 1 && !a
->x
[i
-1])
558 Bug("cmp called with a->x[a->wds-1] == 0");
559 if (j
> 1 && !b
->x
[j
-1])
560 Bug("cmp called with b->x[b->wds-1] == 0");
570 return *xa
< *xb
? -1 : 1;
580 (a
, b
) Bigint
*a
, *b
;
582 (Bigint
*a
, Bigint
*b
)
587 ULong
*xa
, *xae
, *xb
, *xbe
, *xc
;
624 y
= (ULLong
)*xa
++ - *xb
++ - borrow
;
625 borrow
= y
>> 32 & 1UL;
626 *xc
++ = y
& 0xffffffffUL
;
631 borrow
= y
>> 32 & 1UL;
632 *xc
++ = y
& 0xffffffffUL
;
637 y
= (*xa
& 0xffff) - (*xb
& 0xffff) - borrow
;
638 borrow
= (y
& 0x10000) >> 16;
639 z
= (*xa
++ >> 16) - (*xb
++ >> 16) - borrow
;
640 borrow
= (z
& 0x10000) >> 16;
645 y
= (*xa
& 0xffff) - borrow
;
646 borrow
= (y
& 0x10000) >> 16;
647 z
= (*xa
++ >> 16) - borrow
;
648 borrow
= (z
& 0x10000) >> 16;
653 y
= *xa
++ - *xb
++ - borrow
;
654 borrow
= (y
& 0x10000) >> 16;
660 borrow
= (y
& 0x10000) >> 16;
674 (a
, e
) Bigint
*a
; int *e
;
679 ULong
*xa
, *xa0
, w
, y
, z
;
693 if (!y
) Bug("zero y in b2d");
699 d0
= Exp_1
| y
>> (Ebits
- k
);
700 w
= xa
> xa0
? *--xa
: 0;
701 d1
= y
<< ((32-Ebits
) + k
) | w
>> (Ebits
- k
);
704 z
= xa
> xa0
? *--xa
: 0;
706 d0
= Exp_1
| y
<< k
| z
>> (32 - k
);
707 y
= xa
> xa0
? *--xa
: 0;
708 d1
= z
<< k
| y
>> (32 - k
);
715 if (k
< Ebits
+ 16) {
716 z
= xa
> xa0
? *--xa
: 0;
717 d0
= Exp_1
| y
<< k
- Ebits
| z
>> Ebits
+ 16 - k
;
718 w
= xa
> xa0
? *--xa
: 0;
719 y
= xa
> xa0
? *--xa
: 0;
720 d1
= z
<< k
+ 16 - Ebits
| w
<< k
- Ebits
| y
>> 16 + Ebits
- k
;
723 z
= xa
> xa0
? *--xa
: 0;
724 w
= xa
> xa0
? *--xa
: 0;
726 d0
= Exp_1
| y
<< k
+ 16 | z
<< k
| w
>> 16 - k
;
727 y
= xa
> xa0
? *--xa
: 0;
728 d1
= w
<< k
+ 16 | y
<< k
;
732 word0(&d
) = d0
>> 16 | d0
<< 16;
733 word1(&d
) = d1
>> 16 | d1
<< 16;
743 (dd
, e
, bits
) double dd
; int *e
, *bits
;
745 (double dd
, int *e
, int *bits
)
750 #ifndef Sudden_Underflow
763 d0
= word0(&d
) >> 16 | word0(&d
) << 16;
764 d1
= word1(&d
) >> 16 | word1(&d
) << 16;
775 d0
&= 0x7fffffff; /* clear sign bit, which we ignore */
776 #ifdef Sudden_Underflow
777 de
= (int)(d0
>> Exp_shift
);
782 if ( (de
= (int)(d0
>> Exp_shift
)) !=0)
787 if ( (k
= lo0bits(&y
)) !=0) {
788 x
[0] = y
| z
<< (32 - k
);
793 #ifndef Sudden_Underflow
796 b
->wds
= (x
[1] = z
) !=0 ? 2 : 1;
801 #ifndef Sudden_Underflow
809 if ( (k
= lo0bits(&y
)) !=0)
811 x
[0] = y
| z
<< 32 - k
& 0xffff;
812 x
[1] = z
>> k
- 16 & 0xffff;
818 x
[1] = y
>> 16 | z
<< 16 - k
& 0xffff;
819 x
[2] = z
>> k
& 0xffff;
834 Bug("Zero passed to d2b");
852 #ifndef Sudden_Underflow
856 *e
= (de
- Bias
- (P
-1) << 2) + k
;
857 *bits
= 4*P
+ 8 - k
- hi0bits(word0(&d
) & Frac_mask
);
859 *e
= de
- Bias
- (P
-1) + k
;
862 #ifndef Sudden_Underflow
865 *e
= de
- Bias
- (P
-1) + 1 + k
;
867 *bits
= 32*i
- hi0bits(x
[i
-1]);
869 *bits
= (i
+2)*16 - hi0bits(x
[i
]);
880 bigtens
[] = { 1e16
, 1e32
, 1e64
, 1e128
, 1e256
};
881 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
885 bigtens
[] = { 1e16
, 1e32
, 1e64
};
886 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64 };
888 bigtens
[] = { 1e16
, 1e32
};
889 CONST
double tinytens
[] = { 1e-16, 1e-32 };
895 1e0
, 1e1
, 1e2
, 1e3
, 1e4
, 1e5
, 1e6
, 1e7
, 1e8
, 1e9
,
896 1e10
, 1e11
, 1e12
, 1e13
, 1e14
, 1e15
, 1e16
, 1e17
, 1e18
, 1e19
,
905 strcp_D2A(a
, b
) char *a
; char *b
;
907 strcp_D2A(char *a
, CONST
char *b
)
919 memcpy_D2A(a
, b
, len
) Char
*a
; Char
*b
; size_t len
;
921 memcpy_D2A(void *a1
, void *b1
, size_t len
)
924 char *a
= (char*)a1
, *ae
= a
+ len
;
925 char *b
= (char*)b1
, *a0
= a
;
931 #endif /* NO_STRING_H */