1 /* $NetBSD: misc.c,v 1.5 2009/01/30 23:35:35 lukem 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 if ( (rv
= freelist
[k
]) !=0) {
61 freelist
[k
] = rv
->next
;
65 #ifdef Omit_Private_Memory
66 rv
= (Bigint
*)MALLOC(sizeof(Bigint
) + (x
-1)*sizeof(ULong
));
68 len
= (sizeof(Bigint
) + (x
-1)*sizeof(ULong
) + sizeof(double) - 1)
70 if ((double *)(pmem_next
- private_mem
+ len
) <= (double *)PRIVATE_mem
) {
71 rv
= (Bigint
*)(void *)pmem_next
;
75 rv
= (Bigint
*)MALLOC(len
*sizeof(double));
83 rv
->sign
= rv
->wds
= 0;
97 v
->next
= freelist
[v
->k
];
154 (b
, m
, a
) Bigint
*b
; int m
, a
;
156 (Bigint
*b
, int m
, int a
) /* multiply by m and add a */
177 y
= *x
* (ULLong
)m
+ carry
;
179 /* LINTED conversion */
180 *x
++ = y
& 0xffffffffUL
;
184 y
= (xi
& 0xffff) * m
+ carry
;
185 z
= (xi
>> 16) * m
+ (y
>> 16);
187 *x
++ = (z
<< 16) + (y
& 0xffff);
197 if (wds
>= b
->maxwds
) {
207 /* LINTED conversion */
224 if (!(x
& 0xffff0000)) {
228 if (!(x
& 0xff000000)) {
232 if (!(x
& 0xf0000000)) {
236 if (!(x
& 0xc0000000)) {
240 if (!(x
& 0x80000000)) {
242 if (!(x
& 0x40000000))
269 (a
, b
) Bigint
*a
, *b
;
271 (Bigint
*a
, Bigint
*b
)
276 ULong
*x
, *xa
, *xae
, *xb
, *xbe
, *xc
, *xc0
;
287 if (a
->wds
< b
->wds
) {
301 for(x
= c
->x
, xa
= x
+ wc
; x
< xa
; x
++)
309 for(; xb
< xbe
; xc0
++) {
310 if ( (y
= *xb
++) !=0) {
315 z
= *x
++ * (ULLong
)y
+ *xc
+ carry
;
317 /* LINTED conversion */
318 *xc
++ = z
& 0xffffffffUL
;
321 /* LINTED conversion */
327 for(; xb
< xbe
; xb
++, xc0
++) {
328 if ( (y
= *xb
& 0xffff) !=0) {
333 z
= (*x
& 0xffff) * y
+ (*xc
& 0xffff) + carry
;
335 z2
= (*x
++ >> 16) * y
+ (*xc
>> 16) + carry
;
342 if ( (y
= *xb
>> 16) !=0) {
348 z
= (*x
& 0xffff) * y
+ (*xc
>> 16) + carry
;
351 z2
= (*x
++ >> 16) * y
+ (*xc
& 0xffff) + carry
;
359 for(; xb
< xbe
; xc0
++) {
360 if ( (y
= *xb
++) !=0) {
365 z
= *x
++ * y
+ *xc
+ carry
;
375 for(xc0
= c
->x
, xc
= xc0
+ wc
; wc
> 0 && !*--xc
; --wc
) ;
385 (b
, k
) Bigint
*b
; int k
;
390 Bigint
*b1
, *p5
, *p51
;
392 static CONST
int p05
[3] = { 5, 25, 125 };
394 if ( (i
= k
& 3) !=0) {
395 b
= multadd(b
, p05
[i
-1], 0);
400 if (!(k
= (unsigned int)k
>> 2))
402 if ((p5
= p5s
) == 0) {
404 #ifdef MULTIPLE_THREADS
405 ACQUIRE_DTOA_LOCK(1);
427 if (!(k
= (unsigned int)k
>> 1))
429 if ((p51
= p5
->next
) == 0) {
430 #ifdef MULTIPLE_THREADS
431 ACQUIRE_DTOA_LOCK(1);
432 if (!(p51
= p5
->next
)) {
433 p51
= p5
->next
= mult(p5
,p5
);
440 p51
= p5
->next
= mult(p5
,p5
);
454 (b
, k
) Bigint
*b
; int k
;
461 ULong
*x
, *x1
, *xe
, z
;
463 n
= (unsigned int)k
>> kshift
;
466 for(i
= b
->maxwds
; n1
> i
; i
<<= 1)
472 for(i
= 0; i
< n
; i
++)
491 *x1
++ = *x
<< k
& 0xffff | z
;
510 (a
, b
) Bigint
*a
, *b
;
512 (Bigint
*a
, Bigint
*b
)
515 ULong
*xa
, *xa0
, *xb
, *xb0
;
521 if (i
> 1 && !a
->x
[i
-1])
522 Bug("cmp called with a->x[a->wds-1] == 0");
523 if (j
> 1 && !b
->x
[j
-1])
524 Bug("cmp called with b->x[b->wds-1] == 0");
534 return *xa
< *xb
? -1 : 1;
544 (a
, b
) Bigint
*a
, *b
;
546 (Bigint
*a
, Bigint
*b
)
551 ULong
*xa
, *xae
, *xb
, *xbe
, *xc
;
592 y
= (ULLong
)*xa
++ - *xb
++ - borrow
;
593 borrow
= y
>> 32 & 1UL;
594 /* LINTED conversion */
595 *xc
++ = y
& 0xffffffffUL
;
600 borrow
= y
>> 32 & 1UL;
601 /* LINTED conversion */
602 *xc
++ = y
& 0xffffffffUL
;
607 y
= (*xa
& 0xffff) - (*xb
& 0xffff) - borrow
;
608 borrow
= (y
& 0x10000) >> 16;
609 z
= (*xa
++ >> 16) - (*xb
++ >> 16) - borrow
;
610 borrow
= (z
& 0x10000) >> 16;
615 y
= (*xa
& 0xffff) - borrow
;
616 borrow
= (y
& 0x10000) >> 16;
617 z
= (*xa
++ >> 16) - borrow
;
618 borrow
= (z
& 0x10000) >> 16;
623 y
= *xa
++ - *xb
++ - borrow
;
624 borrow
= (y
& 0x10000) >> 16;
630 borrow
= (y
& 0x10000) >> 16;
644 (a
, e
) Bigint
*a
; int *e
;
649 ULong
*xa
, *xa0
, w
, y
, z
;
663 if (!y
) Bug("zero y in b2d");
669 d0
= Exp_1
| y
>> (Ebits
- k
);
670 w
= xa
> xa0
? *--xa
: 0;
671 d1
= y
<< ((32-Ebits
) + k
) | w
>> (Ebits
- k
);
674 z
= xa
> xa0
? *--xa
: 0;
676 d0
= Exp_1
| y
<< k
| z
>> (32 - k
);
677 y
= xa
> xa0
? *--xa
: 0;
678 d1
= z
<< k
| y
>> (32 - k
);
685 if (k
< Ebits
+ 16) {
686 z
= xa
> xa0
? *--xa
: 0;
687 d0
= Exp_1
| y
<< k
- Ebits
| z
>> Ebits
+ 16 - k
;
688 w
= xa
> xa0
? *--xa
: 0;
689 y
= xa
> xa0
? *--xa
: 0;
690 d1
= z
<< k
+ 16 - Ebits
| w
<< k
- Ebits
| y
>> 16 + Ebits
- k
;
693 z
= xa
> xa0
? *--xa
: 0;
694 w
= xa
> xa0
? *--xa
: 0;
696 d0
= Exp_1
| y
<< k
+ 16 | z
<< k
| w
>> 16 - k
;
697 y
= xa
> xa0
? *--xa
: 0;
698 d1
= w
<< k
+ 16 | y
<< k
;
702 word0(d
) = d0
>> 16 | d0
<< 16;
703 word1(d
) = d1
>> 16 | d1
<< 16;
713 (d
, e
, bits
) double d
; int *e
, *bits
;
715 (double d
, int *e
, int *bits
)
719 #ifndef Sudden_Underflow
726 d0
= word0(d
) >> 16 | word0(d
) << 16;
727 d1
= word1(d
) >> 16 | word1(d
) << 16;
743 d0
&= 0x7fffffff; /* clear sign bit, which we ignore */
744 #ifdef Sudden_Underflow
745 de
= (int)(d0
>> Exp_shift
);
750 if ( (de
= (int)(d0
>> Exp_shift
)) !=0)
755 if ( (k
= lo0bits(&y
)) !=0) {
756 x
[0] = y
| z
<< (32 - k
);
761 #ifndef Sudden_Underflow
764 b
->wds
= (x
[1] = z
) !=0 ? 2 : 1;
769 Bug("Zero passed to d2b");
773 #ifndef Sudden_Underflow
781 if ( (k
= lo0bits(&y
)) !=0)
783 x
[0] = y
| z
<< 32 - k
& 0xffff;
784 x
[1] = z
>> k
- 16 & 0xffff;
790 x
[1] = y
>> 16 | z
<< 16 - k
& 0xffff;
791 x
[2] = z
>> k
& 0xffff;
806 Bug("Zero passed to d2b");
824 #ifndef Sudden_Underflow
828 *e
= (de
- Bias
- (P
-1) << 2) + k
;
829 *bits
= 4*P
+ 8 - k
- hi0bits(word0(d
) & Frac_mask
);
831 *e
= de
- Bias
- (P
-1) + k
;
834 #ifndef Sudden_Underflow
837 *e
= de
- Bias
- (P
-1) + 1 + k
;
839 *bits
= 32*i
- hi0bits(x
[i
-1]);
841 *bits
= (i
+2)*16 - hi0bits(x
[i
]);
852 bigtens
[] = { 1e16
, 1e32
, 1e64
, 1e128
, 1e256
};
853 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
857 bigtens
[] = { 1e16
, 1e32
, 1e64
};
858 CONST
double tinytens
[] = { 1e-16, 1e-32, 1e-64 };
860 bigtens
[] = { 1e16
, 1e32
};
861 CONST
double tinytens
[] = { 1e-16, 1e-32 };
867 1e0
, 1e1
, 1e2
, 1e3
, 1e4
, 1e5
, 1e6
, 1e7
, 1e8
, 1e9
,
868 1e10
, 1e11
, 1e12
, 1e13
, 1e14
, 1e15
, 1e16
, 1e17
, 1e18
, 1e19
,
877 strcp_D2A(a
, b
) char *a
; char *b
;
879 strcp_D2A(char *a
, CONST
char *b
)
891 memcpy_D2A(a
, b
, len
) Char
*a
; Char
*b
; size_t len
;
893 memcpy_D2A(void *a1
, void *b1
, size_t len
)
896 char *a
= (char*)a1
, *ae
= a
+ len
;
897 char *b
= (char*)b1
, *a0
= a
;
903 #endif /* NO_STRING_H */