dtoa.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,038 行 · 第 1/5 页

C
2,038
字号
        b = Balloc(k);
        b->x[0] = y9;
        b->wds = 1;
#else
        b = Balloc(k+1);
        b->x[0] = y9 & 0xffff;
        b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
#endif

        i = 9;
        if (9 < nd0) {
                s += 9;
                do b = multadd(b, 10, *s++ - '0');
                        while(++i < nd0);
                s++;
                }
        else
                s += 10;
        for(; i < nd; i++)
                b = multadd(b, 10, *s++ - '0');
        return b;
        }

 static int
hi0bits
#ifdef KR_headers
        (x) register unsigned long x;
#else
        (register unsigned long x)
#endif
{
        register 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;
        }

 static int
lo0bits
#ifdef KR_headers
        (y) unsigned long *y;
#else
        (unsigned long *y)
#endif
{
        register int k;
        register unsigned long 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 & 1)
                        return 32;
                }
        *y = x;
        return k;
        }

 static Bigint *
i2b
#ifdef KR_headers
        (i) int i;
#else
        (int i)
#endif
{
        Bigint *b;

        b = Balloc(1);
        b->x[0] = i;
        b->wds = 1;
        return b;
        }

 static Bigint *
mult
#ifdef KR_headers
        (a, b) Bigint *a, *b;
#else
        (Bigint *a, Bigint *b)
#endif
{
        Bigint *c;
        int k, wa, wb, wc;
        unsigned long carry, y, z;
        unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
#ifdef Pack_32
        unsigned long z2;
#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);
        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 Pack_32
        for(; xb < xbe; xb++, xc0++) {
                if (y = *xb & 0xffff) {
                        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) {
                        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++) {
                        x = xa;
                        xc = xc0;
                        carry = 0;
                        do {
                                z = *x++ * y + *xc + carry;
                                carry = z >> 16;
                                *xc++ = z & 0xffff;
                                }
                                while(x < xae);
                        *xc = carry;
                        }
                }
#endif
        for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
        c->wds = wc;
        return c;
        }

 static Bigint *p5s;

 static Bigint *
pow5mult
#ifdef KR_headers
        (b, k) Bigint *b; int k;
#else
        (Bigint *b, int k)
#endif
{
        Bigint *b1, *p5, *p51;
        int i;
        static int p05[3] = { 5, 25, 125 };

        if (i = k & 3)
                b = multadd(b, p05[i-1], 0);

        if (!(k >>= 2))
                return b;
        if (!(p5 = p5s)) {
                /* first time */
                p5 = p5s = i2b(625);
                p5->next = 0;
                }
        for(;;) {
                if (k & 1) {
                        b1 = mult(b, p5);
                        Bfree(b);
                        b = b1;
                        }
                if (!(k >>= 1))
                        break;
                if (!(p51 = p5->next)) {
                        p51 = p5->next = mult(p5,p5);
                        p51->next = 0;
                        }
                p5 = p51;
                }
        return b;
        }

 static Bigint *
lshift
#ifdef KR_headers
        (b, k) Bigint *b; int k;
#else
        (Bigint *b, int k)
#endif
{
        int i, k1, n, n1;
        Bigint *b1;
        unsigned long *x, *x1, *xe, z;

#ifdef Pack_32
        n = k >> 5;
#else
        n = k >> 4;
#endif
        k1 = b->k;
        n1 = n + b->wds + 1;
        for(i = b->maxwds; n1 > i; i <<= 1)
                k1++;
        b1 = Balloc(k1);
        x1 = b1->x;
        for(i = 0; i < n; i++)
                *x1++ = 0;
        x = b->x;
        xe = x + b->wds;
#ifdef Pack_32
        if (k &= 0x1f) {
                k1 = 32 - k;
                z = 0;
                do {
                        *x1++ = *x << k | z;
                        z = *x++ >> k1;
                        }
                        while(x < xe);
                if (*x1 = z)
                        ++n1;
                }
#else
        if (k &= 0xf) {
                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;
        }

 static int
cmp
#ifdef KR_headers
        (a, b) Bigint *a, *b;
#else
        (Bigint *a, Bigint *b)
#endif
{
        unsigned long *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;
        }

 static Bigint *
diff
#ifdef KR_headers
        (a, b) Bigint *a, *b;
#else
        (Bigint *a, Bigint *b)
#endif
{
        Bigint *c;
        int i, wa, wb;
        long borrow, y; /* We need signed shifts here. */
        unsigned long *xa, *xae, *xb, *xbe, *xc;
#ifdef Pack_32
        long z;
#endif

        i = cmp(a,b);
        if (!i) {
                c = Balloc(0);
                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);
        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 Pack_32
        do {
                y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
                borrow = y >> 16;
                Sign_Extend(borrow, y);
                z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
                borrow = z >> 16;
                Sign_Extend(borrow, z);
                Storeinc(xc, z, y);
                }
                while(xb < xbe);
        while(xa < xae) {
                y = (*xa & 0xffff) + borrow;
                borrow = y >> 16;
                Sign_Extend(borrow, y);
                z = (*xa++ >> 16) + borrow;
                borrow = z >> 16;
                Sign_Extend(borrow, z);
                Storeinc(xc, z, y);
                }
#else
        do {
                y = *xa++ - *xb++ + borrow;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?