📄 dtoa.cpp
字号:
xc0 = c->x;#ifdef USE_LONG_LONG for (; xb < xbe; xc0++) { if ((y = *xb++)) { x = xa; xc = xc0; carry = 0; do { z = *x++ * (unsigned long long)y + *xc + carry; carry = z >> 32; *xc++ = (uint32_t)z & 0xffffffffUL; } while (x < xae); *xc = (uint32_t)carry; } }#else#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; uint32_t 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; uint32_t 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#endif for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } c->wds = wc; return c;}static Bigint* p5s;static int p5s_count;static Bigint* pow5mult(Bigint* b, int k){ static int p05[3] = { 5, 25, 125 }; if (int i = k & 3) b = multadd(b, p05[i - 1], 0); if (!(k >>= 2)) return b;#if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->lock();#endif Bigint* p5 = p5s; if (!p5) { /* first time */ p5 = p5s = i2b(625); p5s_count = 1; } int p5s_count_local = p5s_count;#if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->unlock();#endif int p5s_used = 0; for (;;) { if (k & 1) { Bigint* b1 = mult(b, p5); Bfree(b); b = b1; } if (!(k >>= 1)) break; if (++p5s_used == p5s_count_local) {#if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->lock();#endif if (p5s_used == p5s_count) { ASSERT(!p5->next); p5->next = mult(p5, p5); ++p5s_count; } p5s_count_local = p5s_count;#if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->unlock();#endif } p5 = p5->next; } return b;}static Bigint* lshift(Bigint* b, int k){ Bigint* result = b;#ifdef Pack_32 int n = k >> 5;#else int n = k >> 4;#endif int k1 = b->k; int n1 = n + b->wds + 1; for (int i = b->maxwds; n1 > i; i <<= 1) k1++; if (b->k < k1) result = Balloc(k1); const uint32_t* srcStart = b->x; uint32_t* dstStart = result->x; const uint32_t* src = srcStart + b->wds - 1; uint32_t* dst = dstStart + n1 - 1;#ifdef Pack_32 if (k &= 0x1f) { uint32_t hiSubword = 0; int s = 32 - k; for (; src >= srcStart; --src) { *dst-- = hiSubword | *src >> s; hiSubword = *src << k; } *dst = hiSubword; ASSERT(dst == dstStart + n); result->wds = b->wds + n + (result->x[n1 - 1] != 0); }#else if (k &= 0xf) { uint32_t hiSubword = 0; int s = 16 - k; for (; src >= srcStart; --src) { *dst-- = hiSubword | *src >> s; hiSubword = (*src << k) & 0xffff; } *dst = hiSubword; ASSERT(dst == dstStart + n); result->wds = b->wds + n + (result->x[n1 - 1] != 0); } #endif else { do { *--dst = *src--; } while (src >= srcStart); result->wds = b->wds + n; } for (dst = dstStart + n; dst != dstStart; ) *--dst = 0; if (result != b) Bfree(b); return result;}static int cmp(Bigint* a, Bigint* b){ uint32_t *xa, *xa0, *xb, *xb0; int i, j; i = a->wds; j = b->wds; ASSERT(i <= 1 || a->x[i - 1]); ASSERT(j <= 1 || b->x[j - 1]); 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(Bigint* a, Bigint* b){ Bigint* c; int i, wa, wb; uint32_t *xa, *xae, *xb, *xbe, *xc; 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;#ifdef USE_LONG_LONG unsigned long long borrow = 0; do { unsigned long long y = (unsigned long long)*xa++ - *xb++ - borrow; borrow = y >> 32 & (uint32_t)1; *xc++ = (uint32_t)y & 0xffffffffUL; } while (xb < xbe); while (xa < xae) { unsigned long long y = *xa++ - borrow; borrow = y >> 32 & (uint32_t)1; *xc++ = (uint32_t)y & 0xffffffffUL; }#else uint32_t borrow = 0;#ifdef Pack_32 do { uint32_t y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; borrow = (y & 0x10000) >> 16; uint32_t z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; borrow = (z & 0x10000) >> 16; Storeinc(xc, z, y); } while (xb < xbe); while (xa < xae) { uint32_t y = (*xa & 0xffff) - borrow; borrow = (y & 0x10000) >> 16; uint32_t z = (*xa++ >> 16) - borrow; borrow = (z & 0x10000) >> 16; Storeinc(xc, z, y); }#else do { uint32_t y = *xa++ - *xb++ - borrow; borrow = (y & 0x10000) >> 16; *xc++ = y & 0xffff; } while (xb < xbe); while (xa < xae) { uint32_t y = *xa++ - borrow; borrow = (y & 0x10000) >> 16; *xc++ = y & 0xffff; }#endif#endif while (!*--xc) wa--; c->wds = wa; return c;}static double ulp(double x){ register int32_t L; double a; L = (word0(x) & Exp_mask) - (P - 1) * Exp_msk1;#ifndef Avoid_Underflow#ifndef Sudden_Underflow if (L > 0) {#endif#endif word0(a) = L; word1(a) = 0;#ifndef Avoid_Underflow#ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { word0(a) = 0x80000 >> L; word1(a) = 0; } else { word0(a) = 0; L -= Exp_shift; word1(a) = L >= 31 ? 1 : 1 << 31 - L; } }#endif#endif return dval(a);}static double b2d(Bigint* a, int* e){ uint32_t* xa; uint32_t* xa0; uint32_t w; uint32_t y; uint32_t z; int k; double d;#define d0 word0(d)#define d1 word1(d) xa0 = a->x; xa = xa0 + a->wds; y = *--xa; ASSERT(y); k = hi0bits(y); *e = 32 - k;#ifdef Pack_32 if (k < Ebits) { d0 = Exp_1 | y >> Ebits - k; w = xa > xa0 ? *--xa : 0; d1 = y << (32 - Ebits) + k | w >> Ebits - k; goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { d0 = Exp_1 | y << k | z >> 32 - k; y = xa > xa0 ? *--xa : 0; d1 = z << k | y >> 32 - k; } else { d0 = Exp_1 | y; d1 = 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;#endifret_d:#undef d0#undef d1 return dval(d);}static Bigint* d2b(double d, int* e, int* bits){ Bigint* b; int de, k; uint32_t *x, y, z;#ifndef Sudden_Underflow int i;#endif#define d0 word0(d)#define d1 word1(d)#ifdef Pack_32 b = Balloc(1);#else b = Balloc(2);#endif x = b->x; z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */#ifdef Sudden_Underflow de = (int)(d0 >> Exp_shift);#else if ((de = (int)(d0 >> Exp_shift))) z |= Exp_msk1;#endif#ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | z << 32 - k; z >>= k; } else x[0] = y;#ifndef Sudden_Underflow i =#endif b->wds = (x[1] = z) ? 2 : 1; } else { k = lo0bits(&z); x[0] = z;#ifndef Sudden_Underflow i =#endif b->wds = 1; k += 32; }#else if ((y = d1)) { if ((k = lo0bits(&y))) { 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 { 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 *e = de - Bias - (P - 1) + k; *bits = P - k;#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 d1static double ratio(Bigint* a, Bigint* b){ double da, db; int k, ka, kb; dval(da) = b2d(a, &ka); dval(db) = b2d(b, &kb);#ifdef Pack_32 k = ka - kb + 32 * (a->wds - b->wds);#else k = ka - kb + 16 * (a->wds - b->wds);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -