/* $NetBSD: misc.c,v 1.3.12.1 2008/04/08 21:10:55 jdc Exp $ */ | |
/**************************************************************** | |
The author of this software is David M. Gay. | |
Copyright (C) 1998, 1999 by Lucent Technologies | |
All Rights Reserved | |
Permission to use, copy, modify, and distribute this software and | |
its documentation for any purpose and without fee is hereby | |
granted, provided that the above copyright notice appear in all | |
copies and that both that the copyright notice and this | |
permission notice and warranty disclaimer appear in supporting | |
documentation, and that the name of Lucent or any of its entities | |
not be used in advertising or publicity pertaining to | |
distribution of the software without specific, written prior | |
permission. | |
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. | |
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY | |
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
THIS SOFTWARE. | |
****************************************************************/ | |
/* Please send bug reports to David M. Gay (dmg at acm dot org, | |
* with " at " changed at "@" and " dot " changed to "."). */ | |
#include <LibConfig.h> | |
#include "gdtoaimp.h" | |
#if defined(_MSC_VER) | |
// Disable warnings about assignment within conditional expressions. | |
#pragma warning ( disable : 4706 ) | |
#endif | |
static Bigint *freelist[Kmax+1]; | |
#ifndef Omit_Private_Memory | |
#ifndef PRIVATE_MEM | |
#define PRIVATE_MEM 2304 | |
#endif | |
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) | |
static double private_mem[PRIVATE_mem], *pmem_next = private_mem; | |
#endif | |
Bigint * | |
Balloc | |
#ifdef KR_headers | |
(k) int k; | |
#else | |
(int k) | |
#endif | |
{ | |
int x; | |
Bigint *rv; | |
#ifndef Omit_Private_Memory | |
unsigned int len; | |
#endif | |
ACQUIRE_DTOA_LOCK(0); | |
if ( (rv = freelist[k]) !=0) { | |
freelist[k] = rv->next; | |
} | |
else { | |
x = 1 << k; | |
#ifdef Omit_Private_Memory | |
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); | |
#else | |
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) | |
/sizeof(double); | |
if (pmem_next - private_mem + len <= PRIVATE_mem) { | |
rv = (Bigint*)(void *)pmem_next; | |
pmem_next += len; | |
} | |
else | |
rv = (Bigint*)MALLOC(len*sizeof(double)); | |
#endif | |
if (rv == NULL) | |
return NULL; | |
rv->k = k; | |
rv->maxwds = x; | |
} | |
FREE_DTOA_LOCK(0); | |
rv->sign = rv->wds = 0; | |
return rv; | |
} | |
void | |
Bfree | |
#ifdef KR_headers | |
(v) Bigint *v; | |
#else | |
(Bigint *v) | |
#endif | |
{ | |
if (v) { | |
ACQUIRE_DTOA_LOCK(0); | |
v->next = freelist[v->k]; | |
freelist[v->k] = v; | |
FREE_DTOA_LOCK(0); | |
} | |
} | |
int | |
lo0bits | |
#ifdef KR_headers | |
(y) ULong *y; | |
#else | |
(ULong *y) | |
#endif | |
{ | |
int k; | |
ULong x = *y; | |
if (x & 7) { | |
if (x & 1) | |
return 0; | |
if (x & 2) { | |
*y = x >> 1; | |
return 1; | |
} | |
*y = x >> 2; | |
return 2; | |
} | |
k = 0; | |
if (!(x & 0xffff)) { | |
k = 16; | |
x >>= 16; | |
} | |
if (!(x & 0xff)) { | |
k += 8; | |
x >>= 8; | |
} | |
if (!(x & 0xf)) { | |
k += 4; | |
x >>= 4; | |
} | |
if (!(x & 0x3)) { | |
k += 2; | |
x >>= 2; | |
} | |
if (!(x & 1)) { | |
k++; | |
x >>= 1; | |
if (!x) | |
return 32; | |
} | |
*y = x; | |
return k; | |
} | |
Bigint * | |
multadd | |
#ifdef KR_headers | |
(b, m, a) Bigint *b; int m, a; | |
#else | |
(Bigint *b, int m, int a) /* multiply by m and add a */ | |
#endif | |
{ | |
int i, wds; | |
#ifdef ULLong | |
ULong *x; | |
ULLong carry, y; | |
#else | |
ULong carry, *x, y; | |
#ifdef Pack_32 | |
ULong xi, z; | |
#endif | |
#endif | |
Bigint *b1; | |
wds = b->wds; | |
x = b->x; | |
i = 0; | |
carry = a; | |
do { | |
#ifdef ULLong | |
y = *x * (ULLong)m + carry; | |
carry = y >> 32; | |
/* LINTED conversion */ | |
*x++ = (uint32_t)(y & 0xffffffffUL); | |
#else | |
#ifdef Pack_32 | |
xi = *x; | |
y = (xi & 0xffff) * m + carry; | |
z = (xi >> 16) * m + (y >> 16); | |
carry = z >> 16; | |
*x++ = (z << 16) + (y & 0xffff); | |
#else | |
y = *x * m + carry; | |
carry = y >> 16; | |
*x++ = y & 0xffff; | |
#endif | |
#endif | |
} | |
while(++i < wds); | |
if (carry) { | |
if (wds >= b->maxwds) { | |
b1 = Balloc(b->k+1); | |
if (b1 == NULL) { | |
Bfree(b); | |
return NULL; | |
} | |
Bcopy(b1, b); | |
Bfree(b); | |
b = b1; | |
} | |
/* LINTED conversion */ | |
b->x[wds++] = (uint32_t)carry; | |
b->wds = wds; | |
} | |
return b; | |
} | |
int | |
hi0bits_D2A | |
#ifdef KR_headers | |
(x) ULong x; | |
#else | |
(ULong x) | |
#endif | |
{ | |
int k = 0; | |
if (!(x & 0xffff0000)) { | |
k = 16; | |
x <<= 16; | |
} | |
if (!(x & 0xff000000)) { | |
k += 8; | |
x <<= 8; | |
} | |
if (!(x & 0xf0000000)) { | |
k += 4; | |
x <<= 4; | |
} | |
if (!(x & 0xc0000000)) { | |
k += 2; | |
x <<= 2; | |
} | |
if (!(x & 0x80000000)) { | |
k++; | |
if (!(x & 0x40000000)) | |
return 32; | |
} | |
return k; | |
} | |
Bigint * | |
i2b | |
#ifdef KR_headers | |
(i) int i; | |
#else | |
(int i) | |
#endif | |
{ | |
Bigint *b; | |
b = Balloc(1); | |
if (b == NULL) | |
return NULL; | |
b->x[0] = i; | |
b->wds = 1; | |
return b; | |
} | |
Bigint * | |
mult | |
#ifdef KR_headers | |
(a, b) Bigint *a, *b; | |
#else | |
(Bigint *a, Bigint *b) | |
#endif | |
{ | |
Bigint *c; | |
int k, wa, wb, wc; | |
ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; | |
ULong y; | |
#ifdef ULLong | |
ULLong carry, z; | |
#else | |
ULong carry, z; | |
#ifdef Pack_32 | |
ULong z2; | |
#endif | |
#endif | |
if (a->wds < b->wds) { | |
c = a; | |
a = b; | |
b = c; | |
} | |
k = a->k; | |
wa = a->wds; | |
wb = b->wds; | |
wc = wa + wb; | |
if (wc > a->maxwds) | |
k++; | |
c = Balloc(k); | |
if (c == NULL) | |
return NULL; | |
for(x = c->x, xa = x + wc; x < xa; x++) | |
*x = 0; | |
xa = a->x; | |
xae = xa + wa; | |
xb = b->x; | |
xbe = xb + wb; | |
xc0 = c->x; | |
#ifdef ULLong | |
for(; xb < xbe; xc0++) { | |
if ( (y = *xb++) !=0) { | |
x = xa; | |
xc = xc0; | |
carry = 0; | |
do { | |
z = *x++ * (ULLong)y + *xc + carry; | |
carry = z >> 32; | |
/* LINTED conversion */ | |
*xc++ = (uint32_t)(z & 0xffffffffUL); | |
} | |
while(x < xae); | |
/* LINTED conversion */ | |
*xc = (uint32_t)carry; | |
} | |
} | |
#else | |
#ifdef Pack_32 | |
for(; xb < xbe; xb++, xc0++) { | |
if ( (y = *xb & 0xffff) !=0) { | |
x = xa; | |
xc = xc0; | |
carry = 0; | |
do { | |
z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; | |
carry = z >> 16; | |
z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; | |
carry = z2 >> 16; | |
Storeinc(xc, z2, z); | |
} | |
while(x < xae); | |
*xc = carry; | |
} | |
if ( (y = *xb >> 16) !=0) { | |
x = xa; | |
xc = xc0; | |
carry = 0; | |
z2 = *xc; | |
do { | |
z = (*x & 0xffff) * y + (*xc >> 16) + carry; | |
carry = z >> 16; | |
Storeinc(xc, z, z2); | |
z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; | |
carry = z2 >> 16; | |
} | |
while(x < xae); | |
*xc = z2; | |
} | |
} | |
#else | |
for(; xb < xbe; xc0++) { | |
if ( (y = *xb++) !=0) { | |
x = xa; | |
xc = xc0; | |
carry = 0; | |
do { | |
z = *x++ * y + *xc + carry; | |
carry = z >> 16; | |
*xc++ = z & 0xffff; | |
} | |
while(x < xae); | |
*xc = carry; | |
} | |
} | |
#endif | |
#endif | |
for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; | |
c->wds = wc; | |
return c; | |
} | |
static Bigint *p5s; | |
Bigint * | |
pow5mult | |
#ifdef KR_headers | |
(b, k) Bigint *b; int k; | |
#else | |
(Bigint *b, int k) | |
#endif | |
{ | |
Bigint *b1, *p5, *p51; | |
int i; | |
static CONST int p05[3] = { 5, 25, 125 }; | |
if ( (i = k & 3) !=0) { | |
b = multadd(b, p05[i-1], 0); | |
if (b == NULL) | |
return NULL; | |
} | |
if ((k = (unsigned int)k >> 2) == 0) | |
return b; | |
if ((p5 = p5s) == 0) { | |
/* first time */ | |
#ifdef MULTIPLE_THREADS | |
ACQUIRE_DTOA_LOCK(1); | |
if (!(p5 = p5s)) { | |
p5 = p5s = i2b(625); | |
if (p5 == NULL) | |
return NULL; | |
p5->next = 0; | |
} | |
FREE_DTOA_LOCK(1); | |
#else | |
p5 = p5s = i2b(625); | |
if (p5 == NULL) | |
return NULL; | |
p5->next = 0; | |
#endif | |
} | |
for(;;) { | |
if (k & 1) { | |
b1 = mult(b, p5); | |
if (b1 == NULL) | |
return NULL; | |
b = b1; | |
} | |
if ((k = (unsigned int)k >> 1) == 0) | |
break; | |
if ((p51 = p5->next) == 0) { | |
#ifdef MULTIPLE_THREADS | |
ACQUIRE_DTOA_LOCK(1); | |
if (!(p51 = p5->next)) { | |
p51 = p5->next = mult(p5,p5); | |
if (p51 == NULL) | |
return NULL; | |
p51->next = 0; | |
} | |
FREE_DTOA_LOCK(1); | |
#else | |
p51 = p5->next = mult(p5,p5); | |
if (p51 == NULL) | |
return NULL; | |
p51->next = 0; | |
#endif | |
} | |
p5 = p51; | |
} | |
return b; | |
} | |
Bigint * | |
lshift | |
#ifdef KR_headers | |
(b, k) Bigint *b; int k; | |
#else | |
(Bigint *b, int k) | |
#endif | |
{ | |
int i, k1, n, n1; | |
Bigint *b1; | |
ULong *x, *x1, *xe, z; | |
n = (unsigned int)k >> kshift; | |
k1 = b->k; | |
n1 = n + b->wds + 1; | |
for(i = b->maxwds; n1 > i; i <<= 1) | |
k1++; | |
b1 = Balloc(k1); | |
if (b1 == NULL) | |
return NULL; | |
x1 = b1->x; | |
for(i = 0; i < n; i++) | |
*x1++ = 0; | |
x = b->x; | |
xe = x + b->wds; | |
if (k &= kmask) { | |
#ifdef Pack_32 | |
k1 = 32 - k; | |
z = 0; | |
do { | |
*x1++ = *x << k | z; | |
z = *x++ >> k1; | |
} | |
while(x < xe); | |
if ((*x1 = z) !=0) | |
++n1; | |
#else | |
k1 = 16 - k; | |
z = 0; | |
do { | |
*x1++ = *x << k & 0xffff | z; | |
z = *x++ >> k1; | |
} | |
while(x < xe); | |
if (*x1 = z) | |
++n1; | |
#endif | |
} | |
else do | |
*x1++ = *x++; | |
while(x < xe); | |
b1->wds = n1 - 1; | |
Bfree(b); | |
return b1; | |
} | |
int | |
cmp | |
#ifdef KR_headers | |
(a, b) Bigint *a, *b; | |
#else | |
(Bigint *a, Bigint *b) | |
#endif | |
{ | |
ULong *xa, *xa0, *xb, *xb0; | |
int i, j; | |
i = a->wds; | |
j = b->wds; | |
#ifdef DEBUG | |
if (i > 1 && !a->x[i-1]) | |
Bug("cmp called with a->x[a->wds-1] == 0"); | |
if (j > 1 && !b->x[j-1]) | |
Bug("cmp called with b->x[b->wds-1] == 0"); | |
#endif | |
if (i -= j) | |
return i; | |
xa0 = a->x; | |
xa = xa0 + j; | |
xb0 = b->x; | |
xb = xb0 + j; | |
for(;;) { | |
if (*--xa != *--xb) | |
return *xa < *xb ? -1 : 1; | |
if (xa <= xa0) | |
break; | |
} | |
return 0; | |
} | |
Bigint * | |
diff | |
#ifdef KR_headers | |
(a, b) Bigint *a, *b; | |
#else | |
(Bigint *a, Bigint *b) | |
#endif | |
{ | |
Bigint *c; | |
int i, wa, wb; | |
ULong *xa, *xae, *xb, *xbe, *xc; | |
#ifdef ULLong | |
ULLong borrow, y; | |
#else | |
ULong borrow, y; | |
#ifdef Pack_32 | |
ULong z; | |
#endif | |
#endif | |
i = cmp(a,b); | |
if (!i) { | |
c = Balloc(0); | |
if (c == NULL) | |
return NULL; | |
c->wds = 1; | |
c->x[0] = 0; | |
return c; | |
} | |
if (i < 0) { | |
c = a; | |
a = b; | |
b = c; | |
i = 1; | |
} | |
else | |
i = 0; | |
c = Balloc(a->k); | |
if (c == NULL) | |
return NULL; | |
c->sign = i; | |
wa = a->wds; | |
xa = a->x; | |
xae = xa + wa; | |
wb = b->wds; | |
xb = b->x; | |
xbe = xb + wb; | |
xc = c->x; | |
borrow = 0; | |
#ifdef ULLong | |
do { | |
y = (ULLong)*xa++ - *xb++ - borrow; | |
borrow = y >> 32 & 1UL; | |
/* LINTED conversion */ | |
*xc++ = (uint32_t)(y & 0xffffffffUL); | |
} | |
while(xb < xbe); | |
while(xa < xae) { | |
y = *xa++ - borrow; | |
borrow = y >> 32 & 1UL; | |
/* LINTED conversion */ | |
*xc++ = (uint32_t)(y & 0xffffffffUL); | |
} | |
#else | |
#ifdef Pack_32 | |
do { | |
y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; | |
borrow = (y & 0x10000) >> 16; | |
z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; | |
borrow = (z & 0x10000) >> 16; | |
Storeinc(xc, z, y); | |
} | |
while(xb < xbe); | |
while(xa < xae) { | |
y = (*xa & 0xffff) - borrow; | |
borrow = (y & 0x10000) >> 16; | |
z = (*xa++ >> 16) - borrow; | |
borrow = (z & 0x10000) >> 16; | |
Storeinc(xc, z, y); | |
} | |
#else | |
do { | |
y = *xa++ - *xb++ - borrow; | |
borrow = (y & 0x10000) >> 16; | |
*xc++ = y & 0xffff; | |
} | |
while(xb < xbe); | |
while(xa < xae) { | |
y = *xa++ - borrow; | |
borrow = (y & 0x10000) >> 16; | |
*xc++ = y & 0xffff; | |
} | |
#endif | |
#endif | |
while(!*--xc) | |
wa--; | |
c->wds = wa; | |
return c; | |
} | |
double | |
b2d | |
#ifdef KR_headers | |
(a, e) Bigint *a; int *e; | |
#else | |
(Bigint *a, int *e) | |
#endif | |
{ | |
ULong *xa, *xa0, w, y, z; | |
int k; | |
double d; | |
#ifdef VAX | |
ULong d0, d1; | |
#else | |
#define d0 word0(d) | |
#define d1 word1(d) | |
#endif | |
xa0 = a->x; | |
xa = xa0 + a->wds; | |
y = *--xa; | |
#ifdef DEBUG | |
if (!y) Bug("zero y in b2d"); | |
#endif | |
k = hi0bits(y); | |
*e = 32 - k; | |
#ifdef Pack_32 | |
if (k < Ebits) { | |
d0 = (UINT32)(Exp_1 | y >> (Ebits - k)); | |
w = xa > xa0 ? *--xa : 0; | |
d1 = (UINT32)(y << ((32-Ebits) + k) | w >> (Ebits - k)); | |
goto ret_d; | |
} | |
z = xa > xa0 ? *--xa : 0; | |
if (k -= Ebits) { | |
d0 = (UINT32)(Exp_1 | y << k | z >> (32 - k)); | |
y = xa > xa0 ? *--xa : 0; | |
d1 = (UINT32)(z << k | y >> (32 - k)); | |
} | |
else { | |
d0 = (UINT32)(Exp_1 | y); | |
d1 = (UINT32)z; | |
} | |
#else | |
if (k < Ebits + 16) { | |
z = xa > xa0 ? *--xa : 0; | |
d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; | |
w = xa > xa0 ? *--xa : 0; | |
y = xa > xa0 ? *--xa : 0; | |
d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; | |
goto ret_d; | |
} | |
z = xa > xa0 ? *--xa : 0; | |
w = xa > xa0 ? *--xa : 0; | |
k -= Ebits + 16; | |
d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; | |
y = xa > xa0 ? *--xa : 0; | |
d1 = w << k + 16 | y << k; | |
#endif | |
ret_d: | |
#ifdef VAX | |
word0(d) = d0 >> 16 | d0 << 16; | |
word1(d) = d1 >> 16 | d1 << 16; | |
#endif | |
return dval(d); | |
} | |
#undef d0 | |
#undef d1 | |
Bigint * | |
d2b | |
#ifdef KR_headers | |
(d, e, bits) double d; int *e, *bits; | |
#else | |
(double d, int *e, int *bits) | |
#endif | |
{ | |
Bigint *b; | |
#ifndef Sudden_Underflow | |
int i; | |
#endif | |
int de, k; | |
ULong *x, y, z; | |
#ifdef VAX | |
ULong d0, d1; | |
d0 = word0(d) >> 16 | word0(d) << 16; | |
d1 = word1(d) >> 16 | word1(d) << 16; | |
#else | |
#define d0 word0(d) | |
#define d1 word1(d) | |
#endif | |
#ifdef Pack_32 | |
b = Balloc(1); | |
#else | |
b = Balloc(2); | |
#endif | |
if (b == NULL) | |
return NULL; | |
x = b->x; | |
z = d0 & Frac_mask; | |
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ | |
#ifdef Sudden_Underflow | |
de = (int)(d0 >> Exp_shift); | |
#ifndef IBM | |
z |= Exp_msk11; | |
#endif | |
#else | |
if ( (de = (int)(d0 >> Exp_shift)) !=0) | |
z |= Exp_msk1; | |
#endif | |
#ifdef Pack_32 | |
if ( (y = d1) !=0) { | |
if ( (k = lo0bits(&y)) !=0) { | |
x[0] = y | z << (32 - k); | |
z >>= k; | |
} | |
else | |
x[0] = y; | |
#ifndef Sudden_Underflow | |
i = | |
#endif | |
b->wds = (x[1] = z) !=0 ? 2 : 1; | |
} | |
else { | |
#ifdef DEBUG | |
if (!z) | |
Bug("Zero passed to d2b"); | |
#endif | |
k = lo0bits(&z); | |
x[0] = z; | |
#ifndef Sudden_Underflow | |
i = | |
#endif | |
b->wds = 1; | |
k += 32; | |
} | |
#else | |
if ( (y = d1) !=0) { | |
if ( (k = lo0bits(&y)) !=0) | |
if (k >= 16) { | |
x[0] = y | z << 32 - k & 0xffff; | |
x[1] = z >> k - 16 & 0xffff; | |
x[2] = z >> k; | |
i = 2; | |
} | |
else { | |
x[0] = y & 0xffff; | |
x[1] = y >> 16 | z << 16 - k & 0xffff; | |
x[2] = z >> k & 0xffff; | |
x[3] = z >> k+16; | |
i = 3; | |
} | |
else { | |
x[0] = y & 0xffff; | |
x[1] = y >> 16; | |
x[2] = z & 0xffff; | |
x[3] = z >> 16; | |
i = 3; | |
} | |
} | |
else { | |
#ifdef DEBUG | |
if (!z) | |
Bug("Zero passed to d2b"); | |
#endif | |
k = lo0bits(&z); | |
if (k >= 16) { | |
x[0] = z; | |
i = 0; | |
} | |
else { | |
x[0] = z & 0xffff; | |
x[1] = z >> 16; | |
i = 1; | |
} | |
k += 32; | |
} | |
while(!x[i]) | |
--i; | |
b->wds = i + 1; | |
#endif | |
#ifndef Sudden_Underflow | |
if (de) { | |
#endif | |
#ifdef IBM | |
*e = (de - Bias - (P-1) << 2) + k; | |
*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); | |
#else | |
*e = de - Bias - (P-1) + k; | |
*bits = P - k; | |
#endif | |
#ifndef Sudden_Underflow | |
} | |
else { | |
*e = de - Bias - (P-1) + 1 + k; | |
#ifdef Pack_32 | |
*bits = 32*i - hi0bits(x[i-1]); | |
#else | |
*bits = (i+2)*16 - hi0bits(x[i]); | |
#endif | |
} | |
#endif | |
return b; | |
} | |
#undef d0 | |
#undef d1 | |
CONST double | |
#ifdef IEEE_Arith | |
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; | |
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 | |
}; | |
#else | |
#ifdef IBM | |
bigtens[] = { 1e16, 1e32, 1e64 }; | |
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; | |
#else | |
bigtens[] = { 1e16, 1e32 }; | |
CONST double tinytens[] = { 1e-16, 1e-32 }; | |
#endif | |
#endif | |
CONST double | |
tens[] = { | |
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, | |
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, | |
1e20, 1e21, 1e22 | |
#ifdef VAX | |
, 1e23, 1e24 | |
#endif | |
}; | |
char * | |
#ifdef KR_headers | |
strcp_D2A(a, b) char *a; char *b; | |
#else | |
strcp_D2A(char *a, CONST char *b) | |
#endif | |
{ | |
while((*a = *b++)) | |
a++; | |
return a; | |
} | |
#ifdef NO_STRING_H | |
Char * | |
#ifdef KR_headers | |
memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; | |
#else | |
memcpy_D2A(void *a1, void *b1, size_t len) | |
#endif | |
{ | |
char *a = (char*)a1, *ae = a + len; | |
char *b = (char*)b1, *a0 = a; | |
while(a < ae) | |
*a++ = *b++; | |
return a0; | |
} | |
#endif /* NO_STRING_H */ |