1 /* $NetBSD: misc.c,v 1.11 2011/11/21 09:46:19 mlelstv Exp $ */
3 /****************************************************************
5 The author of this software is David M. Gay.
7 Copyright (C) 1998, 1999 by Lucent Technologies
10 Permission to use, copy, modify, and distribute this software and
11 its documentation for any purpose and without fee is hereby
12 granted, provided that the above copyright notice appear in all
13 copies and that both that the copyright notice and this
14 permission notice and warranty disclaimer appear in supporting
15 documentation, and that the name of Lucent or any of its entities
16 not be used in advertising or publicity pertaining to
17 distribution of the software without specific, written prior
20 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
29 ****************************************************************/
31 /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 * with " at " changed at "@" and " dot " changed to "."). */
36 static Bigint
*freelist
[Kmax
+1];
37 #ifndef Omit_Private_Memory
39 #define PRIVATE_MEM 2304
41 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
42 static double private_mem
[PRIVATE_mem
], *pmem_next
= private_mem
;
55 #ifndef Omit_Private_Memory
60 /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
61 /* but this case seems very unlikely. */
62 if ((size_t)k
<= Kmax
&& (rv
= freelist
[k
]) !=0) {
63 freelist
[k
] = rv
->next
;
67 #ifdef Omit_Private_Memory
68 rv
= (Bigint
*)MALLOC(sizeof(Bigint
) + (x
-1)*sizeof(ULong
));
70 len
= (sizeof(Bigint
) + (x
-1)*sizeof(ULong
) + sizeof(double) - 1)
72 if ((size_t)k
<= Kmax
&& pmem_next
- private_mem
+ len
<= PRIVATE_mem
) {
73 rv
= (Bigint
*)(void *)pmem_next
;
77 rv
= (Bigint
*)MALLOC(len
*sizeof(double));
87 rv
->sign
= rv
->wds
= 0;
100 if ((size_t)v
->k
> Kmax
)
107 ACQUIRE_DTOA_LOCK(0);
108 v
->next
= freelist
[v
->k
];
166 (b
, m
, a
) Bigint
*b
; int m
, a
;
168 (Bigint
*b
, int m
, int a
) /* multiply by m and add a */
189 y
= *x
* (ULLong
)m
+ carry
;
191 /* LINTED conversion */
192 *x
++ = y
& 0xffffffffUL
;
196 y
= (xi
& 0xffff) * m
+ carry
;
197 z
= (xi
>> 16) * m
+ (y
>> 16);
199 *x
++ = (z
<< 16) + (y
& 0xffff);
209 if (wds
>= b
->maxwds
) {
219 /* LINTED conversion */
236 if (!(x
& 0xffff0000)) {
240 if (!(x
& 0xff000000)) {
244 if (!(x
& 0xf0000000)) {
248 if (!(x
& 0xc0000000)) {
252 if (!(x
& 0x80000000)) {
254 if (!(x
& 0x40000000))
281 (a
, b
) Bigint
*a
, *b
;
283 (Bigint
*a
, Bigint
*b
)
288 ULong
*x
, *xa
, *xae
, *xb
, *xbe
, *xc
, *xc0
;
299 if (a
->wds
< b
->wds
) {
313 for(x
= c
->x
, xa
= x
+ wc
; x
< xa
; x
++)
321 for(; xb
< xbe
; xc0
++) {
322 if ( (y
= *xb
++) !=0) {
327 z
= *x
++ * (ULLong
)y
+ *xc
+ carry
;
329 /* LINTED conversion */
330 *xc
++ = z
& 0xffffffffUL
;
333 /* LINTED conversion */
339 for(; xb
< xbe
; xb
++, xc0
++) {
340 if ( (y
= *xb
& 0xffff) !=0) {
345 z
= (*x
& 0xffff) * y
+ (*xc
& 0xffff) + carry
;
347 z2
= (*x
++ >> 16) * y
+ (*xc
>> 16) + carry
;
354 if ( (y
= *xb
>> 16) !=0) {
360 z
= (*x
& 0xffff) * y
+ (*xc
>> 16) + carry
;
363 z2
= (*x
++ >> 16) * y
+ (*xc
& 0xffff) + carry
;
371 for(; xb
< xbe
; xc0
++) {
372 if ( (y
= *xb
++) !=0) {
377 z
= *x
++ * y
+ *xc
+ carry
;
387 for(xc0
= c
->x
, xc
= xc0
+ wc
; wc
> 0 && !*--xc
; --wc
) ;
397 (b
, k
) Bigint
*b
; int k
;
402 Bigint
*b1
, *p5
, *p51
;
404 static CONST
int p05
[3] = { 5, 25, 125 };
406 if ( (i
= k
& 3) !=0) {
407 b
= multadd(b
, p05
[i
-1], 0);
412 if (!(k
= (unsigned int)k
>> 2))
414 if ((p5
= p5s
) == 0) {
416 #ifdef MULTIPLE_THREADS
417 ACQUIRE_DTOA_LOCK(1);
442 if (!(k
= (unsigned int)k
>> 1))
444 if ((p51
= p5
->next
) == 0) {
445 #ifdef MULTIPLE_THREADS
446 ACQUIRE_DTOA_LOCK(1);
447 if (!(p51
= p5
->next
)) {
448 p51
= p5
->next
= mult(p5
,p5
);
457 p51
= p5
->next
= mult(p5
,p5
);
471 (b
, k
) Bigint
*b
; int k
;
478 ULong
*x
, *x1
, *xe
, z
;
480 n
= (unsigned int)k
>> kshift
;
483 for(i
= b
->maxwds
; n1
> i
; i
<<= 1)
489 for(i
= 0; i
< n
; i
++)
508 *x1
++ = *x
<< k
& 0xffff | z
;
527 (a
, b
) Bigint
*a
, *b
;
529 (Bigint
*a
, Bigint
*b
)
532 ULong
*xa
, *xa0
, *xb
, *xb0
;
538 if (i
> 1 && !a
->x
[i
-1])
539 Bug("cmp called with a->x[a->wds-1] == 0");
540 if (j
> 1 && !b
->x
[j
-1])
541 Bug("cmp called with b->x[b->wds-1] == 0");
551 return *xa
< *xb
? -1 : 1;
561 (a
, b
) Bigint
*a
, *b
;
563 (Bigint
*a
, Bigint
*b
)
568 ULong
*xa
, *xae
, *xb
, *xbe
, *xc
;
609 y
= (ULLong
)*xa
++ - *xb
++ - borrow
;
610 borrow
= y
>> 32 & 1UL;
611 /* LINTED conversion */
612 *xc
++ = y
& 0xffffffffUL
;
617 borrow
= y
>> 32 & 1UL;
618 /* LINTED conversion */
619 *xc
++ = y
& 0xffffffffUL
;
624 y
= (*xa
& 0xffff) - (*xb
& 0xffff) - borrow
;
625 borrow
= (y
& 0x10000) >> 16;
626 z
= (*xa
++ >> 16) - (*xb
++ >> 16) - borrow
;
627 borrow
= (z
& 0x10000) >> 16;
632 y
= (*xa
& 0xffff) - borrow
;
633 borrow
= (y
& 0x10000) >> 16;
634 z
= (*xa
++ >> 16) - borrow
;
635 borrow
= (z
& 0x10000) >> 16;
640 y
= *xa
++ - *xb
++ - borrow
;
641 borrow
= (y
& 0x10000) >> 16;
647 borrow
= (y
& 0x10000) >> 16;
661 (a
, e
) Bigint
*a
; int *e
;
666 ULong
*xa
, *xa0
, w
, y
, z
;
680 if (!y
) Bug("zero y in b2d");
686 d0
= Exp_1
| y
>> (Ebits
- k
);
687 w
= xa
> xa0
? *--xa
: 0;
688 d1
= y
<< ((32-Ebits
) + k
) | w
>> (Ebits
- k
);
691 z
= xa
> xa0
? *--xa
: 0;
693 d0
= Exp_1
| y
<< k
| z
>> (32 - k
);
694 y
= xa
> xa0
? *--xa
: 0;
695 d1
= z
<< k
| y
>> (32 - k
);
702 if (k
< Ebits
+ 16) {
703 z
= xa
> xa0
? *--xa
: 0;
704 d0
= Exp_1
| y
<< k
- Ebits
| z
>> Ebits
+ 16 - k
;
705 w
= xa
> xa0
? *--xa
: 0;
706 y
= xa
> xa0
? *--xa
: 0;
707 d1
= z
<< k
+ 16 - Ebits
| w
<< k
- Ebits
| y
>> 16 + Ebits
- k
;
710 z
= xa
> xa0
? *--xa
: 0;
711 w
= xa
> xa0
? *--xa
: 0;
713 d0
= Exp_1
| y
<< k
+ 16 | z
<< k
| w
>> 16 - k
;
714 y
= xa
> xa0
? *--xa
: 0;
715 d1
= w
<< k
+ 16 | y
<< k
;
719 word0(&d
) = d0
>> 16 | d0
<< 16;
720 word1(&d
) = d1
>> 16 | d1
<< 16;
730 (dd
, e
, bits
) double dd
; int *e
, *bits
;
732 (double dd
, int *e
, int *bits
)
737 #ifndef Sudden_Underflow
750 d0
= word0(&d
) >> 16 | word0(&d
) << 16;
751 d1
= word1(&d
) >> 16 | word1(&d
) << 16;
764 d0
&= 0x7fffffff; /* clear sign bit, which we ignore */
765 #ifdef Sudden_Underflow
766 de
= (int)(d0
>> Exp_shift
);
771 if ( (de
= (int)(d0
>> Exp_shift
)) !=0)
776 if ( (k
= lo0bits(&y
)) !=0) {
777 x
[0] = y
| z
<< (32 - k
);
782 #ifndef Sudden_Underflow
785 b
->wds
= (x
[1] = z
) !=0 ? 2 : 1;
790 #ifndef Sudden_Underflow
798 if ( (k
= lo0bits(&y
)) !=0)
800 x
[0] = y
| z
<< 32 - k
& 0xffff;
801 x
[1] = z
>> k
- 16 & 0xffff;
807 x
[1] = y
>> 16 | z
<< 16 - k
& 0xffff;
808 x
[2] = z
>> k
& 0xffff;
823 Bug("Zero passed to d2b");
841 #ifndef Sudden_Underflow
845 *e
= (de
- Bias
- (P
-1) << 2) + k
;
846 *bits
= 4*P
+ 8 - k
- hi0bits(word0(&d
) & Frac_mask
);
848 *e
= de
- Bias
- (P
-1) + k
;
851 #ifndef Sudden_Underflow
854 *e
= de
- Bias
- (P
-1) + 1 + k
;
856 *bits
= 32*i
- hi0bits(x
[i
-1]);
858 *bits
= (i
+2)*16 - hi0bits(x
[i
]);
869 bigtens
[] = { 1e16
, 1e32
, 1e64
, 1e128
, 1e256
};
870 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
874 bigtens
[] = { 1e16
, 1e32
, 1e64
};
875 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64 };
877 bigtens
[] = { 1e16
, 1e32
};
878 CONST
double tinytens
[] = { 1e-16, 1e-32 };
884 1e0
, 1e1
, 1e2
, 1e3
, 1e4
, 1e5
, 1e6
, 1e7
, 1e8
, 1e9
,
885 1e10
, 1e11
, 1e12
, 1e13
, 1e14
, 1e15
, 1e16
, 1e17
, 1e18
, 1e19
,
894 strcp_D2A(a
, b
) char *a
; char *b
;
896 strcp_D2A(char *a
, CONST
char *b
)
908 memcpy_D2A(a
, b
, len
) Char
*a
; Char
*b
; size_t len
;
910 memcpy_D2A(void *a1
, void *b1
, size_t len
)
913 char *a
= (char*)a1
, *ae
= a
+ len
;
914 char *b
= (char*)b1
, *a0
= a
;
920 #endif /* NO_STRING_H */