1
/* $NetBSD: misc.c,v 1.3.12.1 2008/04/08 21:10:55 jdc 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 "."). */
33
#include <LibConfig.h>
38
// Disable warnings about assignment within conditional expressions.
39
#pragma warning ( disable : 4706 )
42
static Bigint *freelist[Kmax+1];
43
#ifndef Omit_Private_Memory
45
#define PRIVATE_MEM 2304
47
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
48
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
61
#ifndef Omit_Private_Memory
66
if ( (rv = freelist[k]) !=0) {
67
freelist[k] = rv->next;
71
#ifdef Omit_Private_Memory
72
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
74
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
76
if (pmem_next - private_mem + len <= PRIVATE_mem) {
77
rv = (Bigint*)(void *)pmem_next;
81
rv = (Bigint*)MALLOC(len*sizeof(double));
89
rv->sign = rv->wds = 0;
102
ACQUIRE_DTOA_LOCK(0);
103
v->next = freelist[v->k];
160
(b, m, a) Bigint *b; int m, a;
162
(Bigint *b, int m, int a) /* multiply by m and add a */
183
y = *x * (ULLong)m + carry;
185
/* LINTED conversion */
186
*x++ = (uint32_t)(y & 0xffffffffUL);
190
y = (xi & 0xffff) * m + carry;
191
z = (xi >> 16) * m + (y >> 16);
193
*x++ = (z << 16) + (y & 0xffff);
203
if (wds >= b->maxwds) {
213
/* LINTED conversion */
214
b->x[wds++] = (uint32_t)carry;
230
if (!(x & 0xffff0000)) {
234
if (!(x & 0xff000000)) {
238
if (!(x & 0xf0000000)) {
242
if (!(x & 0xc0000000)) {
246
if (!(x & 0x80000000)) {
248
if (!(x & 0x40000000))
275
(a, b) Bigint *a, *b;
277
(Bigint *a, Bigint *b)
282
ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
293
if (a->wds < b->wds) {
307
for(x = c->x, xa = x + wc; x < xa; x++)
315
for(; xb < xbe; xc0++) {
316
if ( (y = *xb++) !=0) {
321
z = *x++ * (ULLong)y + *xc + carry;
323
/* LINTED conversion */
324
*xc++ = (uint32_t)(z & 0xffffffffUL);
327
/* LINTED conversion */
328
*xc = (uint32_t)carry;
333
for(; xb < xbe; xb++, xc0++) {
334
if ( (y = *xb & 0xffff) !=0) {
339
z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
341
z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
348
if ( (y = *xb >> 16) !=0) {
354
z = (*x & 0xffff) * y + (*xc >> 16) + carry;
357
z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
365
for(; xb < xbe; xc0++) {
366
if ( (y = *xb++) !=0) {
371
z = *x++ * y + *xc + carry;
381
for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
391
(b, k) Bigint *b; int k;
396
Bigint *b1, *p5, *p51;
398
static CONST int p05[3] = { 5, 25, 125 };
400
if ( (i = k & 3) !=0) {
401
b = multadd(b, p05[i-1], 0);
406
if ((k = (unsigned int)k >> 2) == 0)
408
if ((p5 = p5s) == 0) {
410
#ifdef MULTIPLE_THREADS
411
ACQUIRE_DTOA_LOCK(1);
433
if ((k = (unsigned int)k >> 1) == 0)
435
if ((p51 = p5->next) == 0) {
436
#ifdef MULTIPLE_THREADS
437
ACQUIRE_DTOA_LOCK(1);
438
if (!(p51 = p5->next)) {
439
p51 = p5->next = mult(p5,p5);
446
p51 = p5->next = mult(p5,p5);
460
(b, k) Bigint *b; int k;
467
ULong *x, *x1, *xe, z;
469
n = (unsigned int)k >> kshift;
472
for(i = b->maxwds; n1 > i; i <<= 1)
478
for(i = 0; i < n; i++)
497
*x1++ = *x << k & 0xffff | z;
516
(a, b) Bigint *a, *b;
518
(Bigint *a, Bigint *b)
521
ULong *xa, *xa0, *xb, *xb0;
527
if (i > 1 && !a->x[i-1])
528
Bug("cmp called with a->x[a->wds-1] == 0");
529
if (j > 1 && !b->x[j-1])
530
Bug("cmp called with b->x[b->wds-1] == 0");
540
return *xa < *xb ? -1 : 1;
550
(a, b) Bigint *a, *b;
552
(Bigint *a, Bigint *b)
557
ULong *xa, *xae, *xb, *xbe, *xc;
598
y = (ULLong)*xa++ - *xb++ - borrow;
599
borrow = y >> 32 & 1UL;
600
/* LINTED conversion */
601
*xc++ = (uint32_t)(y & 0xffffffffUL);
606
borrow = y >> 32 & 1UL;
607
/* LINTED conversion */
608
*xc++ = (uint32_t)(y & 0xffffffffUL);
613
y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
614
borrow = (y & 0x10000) >> 16;
615
z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
616
borrow = (z & 0x10000) >> 16;
621
y = (*xa & 0xffff) - borrow;
622
borrow = (y & 0x10000) >> 16;
623
z = (*xa++ >> 16) - borrow;
624
borrow = (z & 0x10000) >> 16;
629
y = *xa++ - *xb++ - borrow;
630
borrow = (y & 0x10000) >> 16;
636
borrow = (y & 0x10000) >> 16;
650
(a, e) Bigint *a; int *e;
655
ULong *xa, *xa0, w, y, z;
669
if (!y) Bug("zero y in b2d");
675
d0 = (UINT32)(Exp_1 | y >> (Ebits - k));
676
w = xa > xa0 ? *--xa : 0;
677
d1 = (UINT32)(y << ((32-Ebits) + k) | w >> (Ebits - k));
680
z = xa > xa0 ? *--xa : 0;
682
d0 = (UINT32)(Exp_1 | y << k | z >> (32 - k));
683
y = xa > xa0 ? *--xa : 0;
684
d1 = (UINT32)(z << k | y >> (32 - k));
687
d0 = (UINT32)(Exp_1 | y);
691
if (k < Ebits + 16) {
692
z = xa > xa0 ? *--xa : 0;
693
d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
694
w = xa > xa0 ? *--xa : 0;
695
y = xa > xa0 ? *--xa : 0;
696
d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
699
z = xa > xa0 ? *--xa : 0;
700
w = xa > xa0 ? *--xa : 0;
702
d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
703
y = xa > xa0 ? *--xa : 0;
704
d1 = w << k + 16 | y << k;
708
word0(d) = d0 >> 16 | d0 << 16;
709
word1(d) = d1 >> 16 | d1 << 16;
719
(d, e, bits) double d; int *e, *bits;
721
(double d, int *e, int *bits)
725
#ifndef Sudden_Underflow
732
d0 = word0(d) >> 16 | word0(d) << 16;
733
d1 = word1(d) >> 16 | word1(d) << 16;
749
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
750
#ifdef Sudden_Underflow
751
de = (int)(d0 >> Exp_shift);
756
if ( (de = (int)(d0 >> Exp_shift)) !=0)
761
if ( (k = lo0bits(&y)) !=0) {
762
x[0] = y | z << (32 - k);
767
#ifndef Sudden_Underflow
770
b->wds = (x[1] = z) !=0 ? 2 : 1;
775
Bug("Zero passed to d2b");
779
#ifndef Sudden_Underflow
787
if ( (k = lo0bits(&y)) !=0)
789
x[0] = y | z << 32 - k & 0xffff;
790
x[1] = z >> k - 16 & 0xffff;
796
x[1] = y >> 16 | z << 16 - k & 0xffff;
797
x[2] = z >> k & 0xffff;
812
Bug("Zero passed to d2b");
830
#ifndef Sudden_Underflow
834
*e = (de - Bias - (P-1) << 2) + k;
835
*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
837
*e = de - Bias - (P-1) + k;
840
#ifndef Sudden_Underflow
843
*e = de - Bias - (P-1) + 1 + k;
845
*bits = 32*i - hi0bits(x[i-1]);
847
*bits = (i+2)*16 - hi0bits(x[i]);
858
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
859
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
863
bigtens[] = { 1e16, 1e32, 1e64 };
864
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
866
bigtens[] = { 1e16, 1e32 };
867
CONST double tinytens[] = { 1e-16, 1e-32 };
873
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
874
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
883
strcp_D2A(a, b) char *a; char *b;
885
strcp_D2A(char *a, CONST char *b)
897
memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
899
memcpy_D2A(void *a1, void *b1, size_t len)
902
char *a = (char*)a1, *ae = a + len;
903
char *b = (char*)b1, *a0 = a;
909
#endif /* NO_STRING_H */