diff --git a/libs/libc/stdio/lib_dtoa.c b/libs/libc/stdio/lib_dtoa.c index cdef4af2b2d..be733dab51e 100644 --- a/libs/libc/stdio/lib_dtoa.c +++ b/libs/libc/stdio/lib_dtoa.c @@ -54,154 +54,180 @@ * Pre-processor Definitions ****************************************************************************/ -#ifdef Unsigned_Shifts -# define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; +#ifdef CONFIG_DTOA_UNSIGNED_SHIFTS +# define SIGN_EXTEND(a,b) if (b < 0) a |= 0xffff0000; #else -# define Sign_Extend(a,b) /* no-op */ +# define SIGN_EXTEND(a,b) /* no-op */ #endif #ifdef CONFIG_ENDIAN_BIG -# define word0(x) ((uint32_t *)&x)[0] -# define word1(x) ((uint32_t *)&x)[1] +# define WORD0(x) ((uint32_t *)&x)[0] +# define WORD1(x) ((uint32_t *)&x)[1] #else -# define word0(x) ((uint32_t *)&x)[1] -# define word1(x) ((uint32_t *)&x)[0] +# define WORD0(x) ((uint32_t *)&x)[1] +# define WORD1(x) ((uint32_t *)&x)[0] #endif #ifdef CONFIG_ENDIAN_BIG -# define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +# define STOREINC(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ ((unsigned short *)a)[1] = (unsigned short)c, a++) #else -# define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +# define STOREINC(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ ((unsigned short *)a)[0] = (unsigned short)c, a++) #endif -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define IEEE_Arith -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ +#define EXP_SHIFT 20 +#define EXP_SHIFT1 20 +#define EXP_MSK1 0x100000 +#define EXP_MSK11 0x100000 +#define EXP_MASK 0x7ff00000 +#define P 53 +#define BIAS 1023 +#define IEEE_ARITH +#define EMIN (-1022) +#define EXP_1 0x3ff00000 +#define EXP_11 0x3ff00000 +#define EBITS 11 +#define FRAC_MASK 0xfffff +#define FRAC_MASK1 0xfffff +#define TEN_PMAX 22 +#define BLETCH 0x10 +#define BNDRY_MASK 0xfffff +#define BNDRY_MASK1 0xfffff +#define LSB 1 +#define SIGN_BIT 0x80000000 +#define LOG2P 1 +#define TINY0 0 +#define TINY1 1 +#define QUICK_MAX 14 +#define SMALL_MAX 14 +#define INFINITE(x) (WORD0(x) == 0x7ff00000) /* sufficient test for here */ -#define Kmax 15 +#define KMAX 15 -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ - y->wds*sizeof(long) + 2*sizeof(int)) +#define BCOPY(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(long) + 2*sizeof(int)) /**************************************************************************** * Private Type Definitions ****************************************************************************/ -struct Bigint +struct bigint_s { - struct Bigint *next; - int k, maxwds, sign, wds; + FAR struct bigint_s *next; + int k; + int maxwds; + int sign; + int wds; unsigned long x[1]; }; -typedef struct Bigint Bigint; +typedef struct bigint_s bigint_t; /**************************************************************************** * Private Data ****************************************************************************/ -static Bigint *freelist[Kmax + 1]; +static FAR bigint_t *g_freelist[KMAX + 1]; +static FAR bigint_t *g_p5s; + +#ifdef IEEE_ARITH +static const double g_bigtens[] = +{ + 1e16, 1e32, 1e64, 1e128, 1e256 +}; + +# define n_bigtens 5 +#else +static const double g_bigtens[] = +{ + 1e16, 1e32 +}; + +# define n_bigtens 2 +#endif /**************************************************************************** * Private Functions ****************************************************************************/ -static Bigint *Balloc(int k) +static FAR bigint_t *balloc(int k) { + FAR bigint_t *rv; int x; - Bigint *rv; - if ((rv = freelist[k])) + if ((rv = g_freelist[k])) { - freelist[k] = rv->next; + g_freelist[k] = rv->next; } else { - x = 1 << k; - rv = (Bigint *)lib_malloc(sizeof(Bigint) + (x - 1) * sizeof(long)); - rv->k = k; - rv->maxwds = x; + x = 1 << k; + rv = (FAR bigint_t *) + lib_malloc(sizeof(bigint_t) + (x - 1) * sizeof(long)); + rv->k = k; + rv->maxwds = x; } - rv->sign = rv->wds = 0; + rv->sign = 0; + rv->wds = 0; return rv; } -static void Bfree(Bigint * v) +static void bfree(FAR bigint_t *v) { - if (v) + if (v != NULL) { - v->next = freelist[v->k]; - freelist[v->k] = v; + v->next = g_freelist[v->k]; + g_freelist[v->k] = v; } } -/* multiply by m and add a */ +/* Multiply by m and add a */ -static Bigint *multadd(Bigint * b, int m, int a) +static FAR bigint_t *multadd(FAR bigint_t *b, int m, int a) { - int i, wds; - unsigned long *x, y; -#ifdef Pack_32 - unsigned long xi, z; + FAR bigint_t *b1; + FAR unsigned long *x; + unsigned long y; +#ifdef CONFIG_DTOA_PACK32 + unsigned long xi; + unsigned long z; #endif - Bigint *b1; + int wds; + int i; wds = b->wds; - x = b->x; - i = 0; + x = b->x; + i = 0; + do { -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + a; - z = (xi >> 16) * m + (y >> 16); - a = (int)(z >> 16); +#ifdef CONFIG_DTOA_PACK32 + xi = *x; + y = (xi & 0xffff) * m + a; + z = (xi >> 16) * m + (y >> 16); + a = (int)(z >> 16); *x++ = (z << 16) + (y & 0xffff); #else - y = *x * m + a; - a = (int)(y >> 16); + y = *x * m + a; + a = (int)(y >> 16); *x++ = y & 0xffff; #endif } while (++i < wds); - if (a) + if (a != 0) { if (wds >= b->maxwds) { - b1 = Balloc(b->k + 1); - Bcopy(b1, b); - Bfree(b); - b = b1; + b1 = balloc(b->k + 1); + BCOPY(b1, b); + bfree(b); + b = b1; } b->x[wds++] = a; - b->wds = wds; + b->wds = wds; } return b; @@ -211,34 +237,34 @@ static int hi0bits(unsigned long x) { int k = 0; - if (!(x & 0xffff0000)) + if ((x & 0xffff0000) == 0) { - k = 16; + k = 16; x <<= 16; } - if (!(x & 0xff000000)) + if ((x & 0xff000000) == 0) { - k += 8; + k += 8; x <<= 8; } - if (!(x & 0xf0000000)) + if ((x & 0xf0000000) == 0) { - k += 4; + k += 4; x <<= 4; } - if (!(x & 0xc0000000)) + if ((x & 0xc0000000) == 0) { - k += 2; + k += 2; x <<= 2; } - if (!(x & 0x80000000)) + if ((x & 0x80000000) == 0) { k++; - if (!(x & 0x40000000)) + if ((x & 0x40000000) == 0) { return 32; } @@ -247,19 +273,19 @@ static int hi0bits(unsigned long x) return k; } -static int lo0bits(unsigned long *y) +static int lo0bits(FAR unsigned long *y) { - int k; unsigned long x = *y; + int k; - if (x & 7) + if ((x & 7) != 0) { if (x & 1) { return 0; } - if (x & 2) + if ((x & 2) != 0) { *y = x >> 1; return 1; @@ -270,35 +296,35 @@ static int lo0bits(unsigned long *y) } k = 0; - if (!(x & 0xffff)) + if ((x & 0xffff) == 0) { - k = 16; + k = 16; x >>= 16; } - if (!(x & 0xff)) + if ((x & 0xff) == 0) { - k += 8; + k += 8; x >>= 8; } - if (!(x & 0xf)) + if ((x & 0xf) == 0) { - k += 4; + k += 4; x >>= 4; } - if (!(x & 0x3)) + if ((x & 0x3) == 0) { - k += 2; + k += 2; x >>= 2; } - if (!(x & 1)) + if ((x & 1) == 0) { k++; x >>= 1; - if (!x & 1) + if ((!x & 1) != 0) { return 32; } @@ -308,25 +334,36 @@ static int lo0bits(unsigned long *y) return k; } -static Bigint *i2b(int i) +static FAR bigint_t *i2b(int i) { - Bigint *b; + FAR bigint_t *b; - b = Balloc(1); + b = balloc(1); b->x[0] = i; - b->wds = 1; + b->wds = 1; return b; } -static Bigint *mult(Bigint * a, Bigint * b) +static FAR bigint_t *mult(FAR bigint_t *a, FAR bigint_t *b) { - Bigint *c; - int k, wa, wb, wc; - unsigned long carry, y, z; - unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0; -#ifdef Pack_32 + FAR bigint_t *c; + FAR unsigned long *x; + FAR unsigned long *xa; + FAR unsigned long *xae; + FAR unsigned long *xb; + FAR unsigned long *xbe; + FAR unsigned long *xc; + FAR unsigned long *xc0; + unsigned long carry; + unsigned long y; + unsigned long z; +#ifdef CONFIG_DTOA_PACK32 uint32_t z2; #endif + int k; + int wa; + int wb; + int wc; if (a->wds < b->wds) { @@ -335,41 +372,44 @@ static Bigint *mult(Bigint * a, Bigint * b) b = c; } - k = a->k; + k = a->k; wa = a->wds; wb = b->wds; wc = wa + wb; + if (wc > a->maxwds) { k++; } - c = Balloc(k); + c = balloc(k); for (x = c->x, xa = x + wc; x < xa; x++) { *x = 0; } - xa = a->x; + xa = a->x; xae = xa + wa; - xb = b->x; + xb = b->x; xbe = xb + wb; xc0 = c->x; -#ifdef Pack_32 + +#ifdef CONFIG_DTOA_PACK32 for (; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff)) + if ((y = *xb & 0xffff) != 0) { - x = xa; - xc = xc0; + x = xa; + xc = xc0; carry = 0; + do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; carry = z2 >> 16; - Storeinc(xc, z2, z); + STOREINC(xc, z2, z); } while (x < xae); @@ -378,16 +418,17 @@ static Bigint *mult(Bigint * a, Bigint * b) if ((y = *xb >> 16)) { - x = xa; - xc = xc0; + x = xa; + xc = xc0; carry = 0; - z2 = *xc; + z2 = *xc; + do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; + z = (*x & 0xffff) * y + (*xc >> 16) + carry; carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + STOREINC(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; carry = z2 >> 16; } while (x < xae); @@ -400,12 +441,13 @@ static Bigint *mult(Bigint * a, Bigint * b) { if ((y = *xb++)) { - x = xa; - xc = xc0; + x = xa; + xc = xc0; carry = 0; + do { - z = *x++ * y + *xc + carry; + z = *x++ * y + *xc + carry; carry = z >> 16; *xc++ = z & 0xffff; } @@ -416,54 +458,59 @@ static Bigint *mult(Bigint * a, Bigint * b) } #endif - for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc); + for (xc0 = c->x, xc = xc0 + wc; wc > 0 && *--xc == 0; --wc); c->wds = wc; return c; } -static Bigint *p5s; - -static Bigint *pow5mult(Bigint * b, int k) +static FAR bigint_t *pow5mult(FAR bigint_t *b, int k) { - Bigint *b1, *p5, *p51; - int i; + FAR bigint_t *b1; + FAR bigint_t *p5; + FAR bigint_t *p51; static int p05[3] = { 5, 25, 125 }; + int i; - if ((i = k & 3)) - b = multadd(b, p05[i - 1], 0); + if ((i = k & 3) != 0) + { + b = multadd(b, p05[i - 1], 0); + } - if (!(k >>= 2)) + if ((k >>= 2) == 0) { return b; } - if (!(p5 = p5s)) + if ((p5 = g_p5s) == 0) { - /* first time */ - p5 = p5s = i2b(625); + /* First time */ + + g_p5s = i2b(625); + p5 = g_p5s; p5->next = 0; } for (; ; ) { - if (k & 1) + if ((k & 1) != 0) { b1 = mult(b, p5); - Bfree(b); - b = b1; + bfree(b); + b = b1; } - if (!(k >>= 1)) + if ((k >>= 1) == 0) { break; } - if (!(p51 = p5->next)) + if ((p51 = p5->next) == 0) { - p51 = p5->next = mult(p5, p5); + p5->next = mult(p5, p5); + p51 = p5->next; p51->next = 0; } @@ -473,63 +520,74 @@ static Bigint *pow5mult(Bigint * b, int k) return b; } -static Bigint *lshift(Bigint * b, int k) +static FAR bigint_t *lshift(FAR bigint_t *b, int k) { - int i, k1, n, n1; - Bigint *b1; - unsigned long *x, *x1, *xe, z; + FAR bigint_t *b1; + FAR unsigned long *x; + FAR unsigned long *x1; + FAR unsigned long *xe; + unsigned long z; + int i; + int k1; + int n; + int n1; -#ifdef Pack_32 +#ifdef CONFIG_DTOA_PACK32 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); + b1 = balloc(k1); x1 = b1->x; + for (i = 0; i < n; i++) { *x1++ = 0; } - x = b->x; + x = b->x; xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) + +#ifdef CONFIG_DTOA_PACK32 + if ((k &= 0x1f) != 0) { k1 = 32 - k; - z = 0; + z = 0; + do { *x1++ = *x << k | z; - z = *x++ >> k1; + z = *x++ >> k1; } while (x < xe); - if ((*x1 = z)) + if ((*x1 = z) != 0) { ++n1; } } #else - if (k &= 0xf) + if ((k &= 0xf) != 0) { k1 = 16 - k; - z = 0; + z = 0; + do { *x1++ = ((*x << k) & 0xffff) | z; - z = *x++ >> k1; + z = *x++ >> k1; } while (x < xe); - if ((*x1 = z)) + if ((*x1 = z) != 0) { ++n1; } @@ -545,25 +603,29 @@ static Bigint *lshift(Bigint * b, int k) } b1->wds = n1 - 1; - Bfree(b); + bfree(b); return b1; } -static int cmp(Bigint * a, Bigint * b) +static int cmp(FAR bigint_t *a, FAR bigint_t *b) { - unsigned long *xa, *xa0, *xb, *xb0; - int i, j; + FAR unsigned long *xa; + FAR unsigned long *xa0; + FAR unsigned long *xb; + FAR unsigned long *xb0; + int i; + int j; i = a->wds; j = b->wds; #ifdef CONFIG_DEBUG_LIB - if (i > 1 && !a->x[i - 1]) + if (i > 1 && a->x[i - 1] == 0) { lerr("ERROR: cmp called with a->x[a->wds-1] == 0\n"); } - if (j > 1 && !b->x[j - 1]) + if (j > 1 && b->x[j - 1] == 0) { lerr("ERROR: cmp called with b->x[b->wds-1] == 0\n"); } @@ -575,9 +637,9 @@ static int cmp(Bigint * a, Bigint * b) } xa0 = a->x; - xa = xa0 + j; + xa = xa0 + j; xb0 = b->x; - xb = xb0 + j; + xb = xb0 + j; for (; ; ) { @@ -595,21 +657,28 @@ static int cmp(Bigint * a, Bigint * b) return 0; } -static Bigint *diff(Bigint * a, Bigint * b) +static FAR bigint_t *diff(FAR bigint_t *a, FAR bigint_t *b) { - Bigint *c; - int i, wa, wb; - long borrow, y; /* We need signed shifts here. */ - unsigned long *xa, *xae, *xb, *xbe, *xc; -#ifdef Pack_32 + FAR bigint_t *c; + FAR unsigned long *xa; + FAR unsigned long *xae; + FAR unsigned long *xb; + FAR unsigned long *xbe; + FAR unsigned long *xc; + long borrow; /* We need signed shifts here. */ + long y; +#ifdef CONFIG_DTOA_PACK32 int32_t z; #endif + int i; + int wa; + int wb; i = cmp(a, b); - if (!i) + if (i == 0) { - c = Balloc(0); - c->wds = 1; + c = balloc(0); + c->wds = 1; c->x[0] = 0; return c; } @@ -626,59 +695,60 @@ static Bigint *diff(Bigint * a, Bigint * b) i = 0; } - c = Balloc(a->k); + 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 + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; + +#ifdef CONFIG_DTOA_PACK32 do { - y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; + y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; + SIGN_EXTEND(borrow, y); + z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); + SIGN_EXTEND(borrow, z); + STOREINC(xc, z, y); } while (xb < xbe); while (xa < xae) { - y = (*xa & 0xffff) + borrow; + y = (*xa & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) + borrow; + SIGN_EXTEND(borrow, y); + z = (*xa++ >> 16) + borrow; borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); + SIGN_EXTEND(borrow, z); + STOREINC(xc, z, y); } #else do { - y = *xa++ - *xb++ + borrow; + y = *xa++ - *xb++ + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; + SIGN_EXTEND(borrow, y); + *xc++ = y & 0xffff; } while (xb < xbe); while (xa < xae) { - y = *xa++ + borrow; + y = *xa++ + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; + SIGN_EXTEND(borrow, y); + *xc++ = y & 0xffff; } #endif - while (!*--xc) + while (*--xc == 0) { wa--; } @@ -687,61 +757,72 @@ static Bigint *diff(Bigint * a, Bigint * b) return c; } -static Bigint *d2b(double d, int *e, int *bits) +static FAR bigint_t *d2b(double d, int *e, int *bits) { - Bigint *b; - int de, i, k; - unsigned long *x, y, z; + FAR bigint_t *b; + FAR unsigned long *x; + unsigned long y; + unsigned long z; + int de; + int i; + int k; -#ifdef Pack_32 - b = Balloc(1); +#ifdef CONFIG_DTOA_PACK32 + b = balloc(1); #else - b = Balloc(2); + b = balloc(2); #endif x = b->x; - z = word0(d) & Frac_mask; - word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ - if ((de = (int)(word0(d) >> Exp_shift))) - z |= Exp_msk1; -#ifdef Pack_32 - if ((y = word1(d))) + z = WORD0(d) & FRAC_MASK; + WORD0(d) &= 0x7fffffff; /* Clear sign bit, which we ignore */ + + de = (int)(WORD0(d) >> EXP_SHIFT); + if (de != 0) { - if ((k = lo0bits(&y))) + z |= EXP_MSK1; + } + +#ifdef CONFIG_DTOA_PACK32 + if ((y = WORD1(d)) != 0) + { + if ((k = lo0bits(&y)) != 0) { x[0] = y | z << (32 - k); - z >>= k; + z >>= k; } else { x[0] = y; } - i = b->wds = (x[1] = z) ? 2 : 1; + b->wds = (x[1] = z) ? 2 : 1; + i = b->wds; } else { #ifdef CONFIG_DEBUG_LIB - if (!z) + if (z == 0) { lerr("ERROR: Zero passed to d2b\n"); } #endif - k = lo0bits(&z); + + k = lo0bits(&z); x[0] = z; - i = b->wds = 1; - k += 32; + i = b->wds = 1; + k += 32; } #else - if ((y = word1(d))) + if ((y = WORD1(d)) != 0) { - if ((k = lo0bits(&y))) + 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; + i = 2; } else { @@ -749,7 +830,7 @@ static Bigint *d2b(double d, int *e, int *bits) x[1] = (y >> 16) | ((z << (16 - k)) & 0xffff); x[2] = z >> k & 0xffff; x[3] = z >> (k + 16); - i = 3; + i = 3; } else { @@ -757,13 +838,13 @@ static Bigint *d2b(double d, int *e, int *bits) x[1] = y >> 16; x[2] = z & 0xffff; x[3] = z >> 16; - i = 3; + i = 3; } } else { #ifdef CONFIG_DEBUG_LIB - if (!z) + if (z == 0) { lerr("ERROR: Zero passed to d2b\n"); } @@ -772,31 +853,34 @@ static Bigint *d2b(double d, int *e, int *bits) if (k >= 16) { x[0] = z; - i = 0; + i = 0; } else { x[0] = z & 0xffff; x[1] = z >> 16; - i = 1; + i = 1; } k += 32; } + while (!x[i]) - --i; + { + --i; + } b->wds = i + 1; #endif - if (de) + if (de != 0) { - *e = de - Bias - (P - 1) + k; + *e = de - BIAS - (P - 1) + k; *bits = P - k; } else { - *e = de - Bias - (P - 1) + 1 + k; -#ifdef Pack_32 + *e = de - BIAS - (P - 1) + 1 + k; +#ifdef CONFIG_DTOA_PACK32 *bits = 32 * i - hi0bits(x[i - 1]); #else *bits = (i + 2) * 16 - hi0bits(x[i]); @@ -813,34 +897,25 @@ static const double tens[] = 1e20, 1e21, 1e22 }; -#ifdef IEEE_Arith -static const double bigtens[] = +static int quorem(FAR bigint_t *b, FAR bigint_t *s) { - 1e16, 1e32, 1e64, 1e128, 1e256 -}; - -# define n_bigtens 5 -#else -static const double bigtens[] = -{ - 1e16, 1e32 -}; - -# define n_bigtens 2 -#endif - -static int quorem(Bigint * b, Bigint * S) -{ - int n; - long borrow, y; - unsigned long carry, q, ys; - unsigned long *bx, *bxe, *sx, *sxe; -#ifdef Pack_32 + long borrow; + long y; + unsigned long carry; + unsigned long q; + unsigned long ys; + FAR unsigned long *bx; + FAR unsigned long *bxe; + FAR unsigned long *sx; + FAR unsigned long *sxe; +#ifdef CONFIG_DTOA_PACK32 int32_t z; - uint32_t si, zs; + uint32_t si; + uint32_t zs; #endif + int n; - n = S->wds; + n = s->wds; #ifdef CONFIG_DEBUG_LIB if (b->wds > n) @@ -854,11 +929,11 @@ static int quorem(Bigint * b, Bigint * S) return 0; } - sx = S->x; + sx = s->x; sxe = sx + --n; - bx = b->x; + bx = b->x; bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ #ifdef CONFIG_DEBUG_LIB if (q > 9) @@ -867,40 +942,40 @@ static int quorem(Bigint * b, Bigint * S) } #endif - if (q) + if (q != 0) { borrow = 0; - carry = 0; + carry = 0; do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; +#ifdef CONFIG_DTOA_PACK32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; + SIGN_EXTEND(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); + SIGN_EXTEND(borrow, z); + STOREINC(bx, z, y); #else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; + SIGN_EXTEND(borrow, y); + *bx++ = y & 0xffff; #endif } while (sx <= sxe); - if (!*bxe) + if (*bxe == 0) { bx = b->x; - while (--bxe > bx && !*bxe) + while (--bxe > bx && *bxe == 0) { --n; } @@ -909,45 +984,48 @@ static int quorem(Bigint * b, Bigint * S) } } - if (cmp(b, S) >= 0) + if (cmp(b, s) >= 0) { q++; borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; + carry = 0; + bx = b->x; + sx = s->x; do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; +#ifdef CONFIG_DTOA_PACK32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; + SIGN_EXTEND(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); + SIGN_EXTEND(borrow, z); + STOREINC(bx, z, y); #else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; + SIGN_EXTEND(borrow, y); + *bx++ = y & 0xffff; #endif } while (sx <= sxe); - bx = b->x; + bx = b->x; bxe = bx + n; - if (!*bxe) + + if (*bxe == 0) { - while (--bxe > bx && !*bxe) - --n; + while (--bxe > bx && *bxe == 0) + { + --n; + } b->wds = n; } @@ -994,153 +1072,192 @@ static int quorem(Bigint * b, Bigint * S) * calculation. */ -char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +FAR char *__dtoa(double d, int mode, int ndigits, FAR int *decpt, + FAR int *sign, FAR char **rve) { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; - * trailing zeros are suppressed from the returned string. If not null, *rve - * is set to point to the end of the return value. If d is +-Infinity or - * NaN, then *decpt is set to 9999. + * trailing zeros are suppressed from the returned string. If not null, + * *rve is set to point to the end of the return value. If d is +-Infinity + * or NaN, then *decpt is set to 9999. * * mode: 0 ==> shortest string that yields d when read in and rounded to * nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with * IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives - * 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives - * a return value similar to that of ecvt, except that trailing zeros are - * suppressed. 3 ==> through ndigits past the decimal point. This gives a - * return value similar to that from fcvt, except that trailing zeros are - * suppressed, and ndigits can be negative. 4-9 should give the same return - * values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode 2 + (mode & - * 1). These modes are mainly for debugging; often they run slower but - * sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit - * generation. 6-9 ==> don't try fast floating-point estimate (if + * 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This + * gives a return value similar to that of ecvt, except that trailing zeros + * are suppressed. 3 ==> through ndigits past the decimal point. This + * gives a return value similar to that from fcvt, except that trailing + * zeros are suppressed, and ndigits can be negative. 4-9 should give the + * same return values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode + * 2 + (mode & 1). These modes are mainly for debugging; often they run + * slower but sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right + * digit generation. 6-9 ==> don't try fast floating-point estimate (if * applicable). * * Values of mode other than 0-9 are treated as mode 0. * * Sufficient space is allocated to the return value to hold the suppressed - * trailing zeros. */ + * trailing zeros. + */ - int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, - j, j_1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case = 0, try_quick; - long L; - int denorm; - unsigned long x; - Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S; - double d2, ds, eps; - char *s, *s0; - static Bigint *result; + static FAR bigint_t *result; static int result_k; + FAR bigint_t *b; + FAR bigint_t *b1; + FAR bigint_t *delta; + FAR bigint_t *mlo = NULL; + FAR bigint_t *mhi; + FAR bigint_t *s; + FAR char *st; + FAR char *st0; + double d2; + double ds; + double eps; + long l; + unsigned long x; + int denorm; + int bbits; + int b2; + int b5; + int be; + int dig; + int i; + int ieps; + int ilim = 0; + int ilim0; + int ilim1 = 0; + int j; + int j_1; + int k; + int k0; + int k_check; + int leftright; + int m2; + int m5; + int s2; + int s5; + int spec_case = 0; + int try_quick; - if (result) + if (result != 0) { - result->k = result_k; + result->k = result_k; result->maxwds = 1 << result_k; - Bfree(result); - result = 0; + bfree(result); + result = 0; } - if (word0(d) & Sign_bit) + if ((WORD0(d) & SIGN_BIT) != 0) { /* Set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ + *sign = 1; + WORD0(d) &= ~SIGN_BIT; /* clear sign bit */ } else { - *sign = 0; + *sign = 0; } -#if defined(IEEE_Arith) -# ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) +#if defined(IEEE_ARITH) +# ifdef IEEE_ARITH + if ((WORD0(d) & EXP_MASK) == EXP_MASK) #else - if (word0(d) == 0x8000) + if (WORD0(d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; - s = -#ifdef IEEE_Arith - !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : + st = +#ifdef IEEE_ARITH + !WORD1(d) && !(WORD0(d) & 0xfffff) ? "Infinity" : #endif "NaN"; - if (rve) + + if (rve != NULL) { *rve = -#ifdef IEEE_Arith - s[3] ? s + 8 : +#ifdef IEEE_ARITH + st[3] ? st + 8 : #endif - s + 3; + st + 3; } - return s; + return st; } #endif - if (!d) + if (d == 0) { *decpt = 1; - s = "0"; - if (rve) + st = "0"; + + if (rve != NULL) { - *rve = s + 1; + *rve = st + 1; } - return s; + return st; } b = d2b(d, &be, &bbits); - if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) + i = (int)(WORD0(d) >> EXP_SHIFT1 & (EXP_MASK >> EXP_SHIFT1)); + if (i != 0) { - d2 = d; - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; + d2 = d; + WORD0(d2) &= FRAC_MASK1; + WORD0(d2) |= EXP_11; /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 log10(x) = log(x) / log(10) ~=~ * log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) log10(d) = - * (i-Bias)*log(2)/log(10) + log10(d2) This suggests computing an - * approximation k to log10(d) by k = (i - Bias)*0.301029995663981 + ( - * (d2-1.5)*0.289529654602168 + 0.176091259055681 ); We want k to be too - * large rather than too small. The error in the first-order Taylor - * series approximation is in our favor, so we just round up the constant - * enough to compensate for any error in the multiplication of (i - Bias) - * by 0.301029995663981; since |i - Bias| <= 1077, and 1077 * 0.30103 * - * 2^-52 ~=~ 7.2e-14, adding 1e-13 to the constant term more than - * suffices. Hence we adjust the constant term to 0.1760912590558. (We - * could get a more accurate k by invoking log10, but this is probably - * not worthwhile.) */ + * (i-BIAS)*log(2)/log(10) + log10(d2) This suggests computing an + * approximation k to log10(d) by k = (i - BIAS)*0.301029995663981 + ( + * (d2-1.5)*0.289529654602168 + 0.176091259055681 ); We want k to be + * too large rather than too small. The error in the first-order Taylor + * series approximation is in our favor, so we just round up the + * constant enough to compensate for any error in the multiplication of + * (i - BIAS) by 0.301029995663981; since |i - BIAS| <= 1077, and + * 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, adding 1e-13 to the constant + * term more than suffices. Hence we adjust the constant term to + * 0.1760912590558. (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ - i -= Bias; + i -= BIAS; denorm = 0; } else { /* d is denormalized */ - i = bbits + be + (Bias + (P - 1) - 1); - x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) - : word1(d) << (32 - i); - d2 = x; - word0(d2) -= 31 * Exp_msk1; /* adjust exponent */ - i -= (Bias + (P - 1) - 1) + 1; - denorm = 1; + i = bbits + be + (BIAS + (P - 1) - 1); + x = i > 32 ? WORD0(d) << (64 - i) | WORD1(d) >> (i - 32) : + WORD1(d) << (32 - i); + d2 = x; + WORD0(d2) -= 31 * EXP_MSK1; /* Adjust exponent */ + i -= (BIAS + (P - 1) - 1) + 1; + denorm = 1; } - ds = (d2 - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981; - k = (int)ds; + ds = (d2 - 1.5) * 0.289529654602168 + 0.1760912590558 + + i * 0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) { - k--; /* want k = floor(ds) */ + k--; /* Want k = floor(ds) */ } k_check = 1; - if (k >= 0 && k <= Ten_pmax) + if (k >= 0 && k <= TEN_PMAX) { if (d < tens[k]) - k--; + { + k--; + } + k_check = 0; } @@ -1158,15 +1275,15 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (k >= 0) { - b5 = 0; - s5 = k; + b5 = 0; + s5 = k; s2 += k; } else { b2 -= k; - b5 = -k; - s5 = 0; + b5 = -k; + s5 = 0; } if (mode < 0 || mode > 9) @@ -1177,7 +1294,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) try_quick = 1; if (mode > 5) { - mode -= 4; + mode -= 4; try_quick = 0; } @@ -1193,23 +1310,30 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) case 2: leftright = 0; + /* FALLTHROUGH */ + case 4: if (ndigits <= 0) { ndigits = 1; } - ilim = ilim1 = i = ndigits; + i = ndigits; + ilim1 = i; + ilim = i; break; case 3: leftright = 0; + /* FALLTHROUGH */ + case 5: - i = ndigits + k + 1; - ilim = i; + i = ndigits + k + 1; + ilim = i; ilim1 = i - 1; + if (i <= 0) { i = 1; @@ -1218,36 +1342,37 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) j = sizeof(unsigned long); for (result_k = 0; - (signed)(sizeof(Bigint) - sizeof(unsigned long) + j) <= i; + (signed)(sizeof(bigint_t) - sizeof(unsigned long) + j) <= i; j <<= 1) { result_k++; } - result = Balloc(result_k); - s = s0 = (char *)result; + result = balloc(result_k); + st0 = (FAR char *)result; + st = st0; - if (ilim >= 0 && ilim <= Quick_max && try_quick) + if (ilim >= 0 && ilim <= QUICK_MAX && try_quick) { /* Try to get by with floating-point arithmetic. */ - i = 0; - d2 = d; - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* Conservative */ if (k > 0) { ds = tens[k & 0xf]; - j = k >> 4; + j = k >> 4; - if (j & Bletch) + if ((j & BLETCH) != 0) { /* Prevent overflows */ - j &= Bletch - 1; - d /= bigtens[n_bigtens - 1]; + j &= BLETCH - 1; + d /= g_bigtens[n_bigtens - 1]; ieps++; } @@ -1256,7 +1381,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (j & 1) { ieps++; - ds *= bigtens[i]; + ds *= g_bigtens[i]; } } @@ -1267,10 +1392,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) d *= tens[j_1 & 0xf]; for (j = j_1 >> 4; j; j >>= 1, i++) { - if (j & 1) + if ((j & 1) != 0) { ieps++; - d *= bigtens[i]; + d *= g_bigtens[i]; } } } @@ -1284,26 +1409,33 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) ilim = ilim1; k--; - d *= 10.; + d *= 10.; ieps++; } - eps = ieps * d + 7.; - word0(eps) -= (P - 1) * Exp_msk1; + eps = ieps * d + 7.; + WORD0(eps) -= (P - 1) * EXP_MSK1; + if (ilim == 0) { - S = mhi = 0; - d -= 5.; + mhi = 0; + s = 0; + d -= 5.; + if (d > eps) - goto one_digit; + { + goto one_digit; + } if (d < -eps) - goto no_digits; + { + goto no_digits; + } goto fast_failed; } -#ifndef No_leftright +#ifndef CONFIG_DTOA_NO_LEFTRIGHT if (leftright) { /* Use Steele & White method of only generating digits needed. */ @@ -1311,9 +1443,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) eps = 0.5 / tens[ilim - 1] - eps; for (i = 0; ; ) { - L = (int)d; - d -= L; - *s++ = '0' + (int)L; + l = (int)d; + d -= l; + *st++ = '0' + (int)l; + if (d < eps) { goto ret1; @@ -1330,7 +1463,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) } eps *= 10.; - d *= 10.; + d *= 10.; } } else @@ -1341,9 +1474,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) eps *= tens[ilim - 1]; for (i = 1; ; i++, d *= 10.) { - L = (int)d; - d -= L; - *s++ = '0' + (int)L; + l = (int)d; + d -= l; + *st++ = '0' + (int)l; + if (i == ilim) { if (d > 0.5 + eps) @@ -1352,35 +1486,38 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) } else if (d < 0.5 - eps) { - while (*--s == '0'); - s++; + while (*--st == '0') + { + } + + st++; goto ret1; } break; } } -#ifndef No_leftright +#ifndef CONFIG_DTOA_NO_LEFTRIGHT } #endif - fast_failed: - s = s0; - d = d2; - k = k0; +fast_failed: + st = st0; + d = d2; + k = k0; ilim = ilim0; } /* Do we have a "small" integer? */ - if (be >= 0 && k <= Int_max) + if (be >= 0 && k <= SMALL_MAX) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; + s = mhi = 0; if (ilim < 0 || d <= 5 * ds) { goto no_digits; @@ -1391,40 +1528,42 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) for (i = 1; ; i++) { - L = (int)(d / ds); - d -= L * ds; + l = (int)(d / ds); + d -= l * ds; #ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + /* If FLT_ROUNDS == 2, l will usually be high by 1 */ if (d < 0) { - L--; + l--; d += ds; } #endif - *s++ = '0' + (int)L; + *st++ = '0' + (int)l; if (i == ilim) { d += d; - if (d > ds || (d == ds && (L & 1))) + if (d > ds || (d == ds && (l & 1))) { - bump_up: - while (*--s == '9') - if (s == s0) - { - k++; - *s = '0'; - break; - } +bump_up: + while (*--st == '9') + { + if (st == st0) + { + k++; + *st = '0'; + break; + } + } - ++*s++; + ++*st++; } break; } - if (!(d *= 10.)) + if ((d *= 10.) == 0) { break; } @@ -1433,31 +1572,34 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) goto ret1; } - m2 = b2; - m5 = b5; + m2 = b2; + m5 = b5; mhi = mlo = 0; + if (leftright) { if (mode < 2) { - i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits; + i = denorm ? be + (BIAS + (P - 1) - 1 + 1) : 1 + P - bbits; } else { j = ilim - 1; if (m5 >= j) - m5 -= j; + { + m5 -= j; + } else { s5 += j -= m5; b5 += j; - m5 = 0; + m5 = 0; } if ((i = ilim) < 0) { m2 -= i; - i = 0; + i = 0; } } @@ -1468,7 +1610,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; + i = m2 < s2 ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; @@ -1481,12 +1623,12 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (m5 > 0) { mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; + b1 = mult(mhi, b); + bfree(b); + b = b1; } - if ((j = b5 - m5)) + if ((j = b5 - m5) != 0) { b = pow5mult(b, j); } @@ -1497,22 +1639,23 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) } } - S = i2b(1); + s = i2b(1); if (s5 > 0) { - S = pow5mult(S, s5); + s = pow5mult(s, s5); } /* Check for special case that d is a normalized power of 2. */ if (mode < 2) { - if (!word1(d) && !(word0(d) & Bndry_mask) && word0(d) & Exp_mask) + if (WORD1(d) == 0 && (WORD0(d) & BNDRY_MASK) == 0 && + (WORD0(d) & EXP_MASK) != 0) { /* The special case */ - b2 += Log2P; - s2 += Log2P; + b2 += LOG2P; + s2 += LOG2P; spec_case = 1; } else @@ -1524,18 +1667,20 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) /* Arrange for convenient computation of quotients: shift left if * necessary so divisor has 4 leading 0 bits. * - * Perhaps we should just compute leading 28 bits of S once and for all + * Perhaps we should just compute leading 28 bits of s once and for all * and pass them and a shift to quorem, so it can do shifts and ors * to compute the numerator for q. */ -#ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0x1f)) +#ifdef CONFIG_DTOA_PACK32 + i = ((s5 ? 32 - hi0bits(s->x[s->wds - 1]) : 1) + s2) & 0x1f; + if (i != 0) { i = 32 - i; } #else - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0xf)) + i = ((s5 ? 32 - hi0bits(s->x[s->wds - 1]) : 1) + s2) & 0xf; + if (i != 0) { i = 16 - i; } @@ -1543,14 +1688,14 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (i > 4) { - i -= 4; + i -= 4; b2 += i; m2 += i; s2 += i; } else if (i < 4) { - i += 28; + i += 28; b2 += i; m2 += i; s2 += i; @@ -1563,12 +1708,12 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (s2 > 0) { - S = lshift(S, s2); + s = lshift(s, s2); } if (k_check) { - if (cmp(b, S) < 0) + if (cmp(b, s) < 0) { k--; b = multadd(b, 10, 0); /* we botched the k estimate */ @@ -1583,17 +1728,17 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (ilim <= 0 && mode > 2) { - if (ilim < 0 || cmp(b, S = multadd(S, 5, 0)) <= 0) + if (ilim < 0 || cmp(b, s = multadd(s, 5, 0)) <= 0) { /* no digits, fcvt style */ - no_digits: +no_digits: k = -1 - ndigits; goto ret; } - one_digit: - *s++ = '1'; +one_digit: + *st++ = '1'; k++; goto ret; } @@ -1606,26 +1751,29 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) } /* Compute mlo -- check for special case that d is a normalized power of - * 2. */ + * 2. + */ mlo = mhi; if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); + mhi = balloc(mhi->k); + BCOPY(mhi, mlo); + mhi = lshift(mhi, LOG2P); } for (i = 1; ; i++) { - dig = quorem(b, S) + '0'; + dig = quorem(b, s) + '0'; + /* Do we yet have the shortest decimal string that will round to d? */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j_1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j_1 == 0 && !mode && !(word1(d) & 1)) + + j = cmp(b, mlo); + delta = diff(s, mhi); + j_1 = delta->sign ? 1 : cmp(b, delta); + bfree(delta); +#ifndef CONFIG_DTOA_ROUND_BIASED + if (j_1 == 0 && !mode && !(WORD1(d) & 1)) { if (dig == '9') { @@ -1637,27 +1785,28 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) dig++; } - *s++ = dig; + *st++ = dig; goto ret; } #endif if (j < 0 || (j == 0 && !mode -#ifndef ROUND_BIASED - && (!(word1(d) & 1)) +#ifndef CONFIG_DTOA_ROUND_BIASED + && ((WORD1(d) & 1) == 0) #endif )) { if ((j_1 > 0)) { - b = lshift(b, 1); - j_1 = cmp(b, S); + b = lshift(b, 1); + j_1 = cmp(b, s); + if ((j_1 > 0 || (j_1 == 0 && (dig & 1))) && dig++ == '9') { goto round_9_up; } } - *s++ = dig; + *st++ = dig; goto ret; } @@ -1665,18 +1814,18 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) { if (dig == '9') { - /* possible if i == 1 */ + /* Possible if i == 1 */ round_9_up: - *s++ = '9'; + *st++ = '9'; goto roundoff; } - *s++ = dig + 1; + *st++ = dig + 1; goto ret; } - *s++ = dig; + *st++ = dig; if (i == ilim) { break; @@ -1685,7 +1834,8 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) b = multadd(b, 10, 0); if (mlo == mhi) { - mlo = mhi = multadd(mhi, 10, 0); + mhi = multadd(mhi, 10, 0); + mlo = mhi; } else { @@ -1698,7 +1848,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) { for (i = 1; ; i++) { - *s++ = dig = quorem(b, S) + '0'; + *st++ = dig = quorem(b, s) + '0'; if (i >= ilim) { break; @@ -1711,53 +1861,60 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) /* Round off last digit */ b = lshift(b, 1); - j = cmp(b, S); + j = cmp(b, s); + if (j > 0 || (j == 0 && (dig & 1))) { - roundoff: - while (*--s == '9') - if (s == s0) - { - k++; - *s++ = '1'; - goto ret; - } +roundoff: + while (*--st == '9') + { + if (st == st0) + { + k++; + *st++ = '1'; + goto ret; + } + } - ++*s++; + ++*st++; } else { - while (*--s == '0'); - s++; + while (*--st == '0') + { + } + + st++; } ret: - Bfree(S); + bfree(s); if (mhi) { if (mlo && mlo != mhi) { - Bfree(mlo); + bfree(mlo); } - Bfree(mhi); + bfree(mhi); } + ret1: - Bfree(b); - if (s == s0) + bfree(b); + if (st == st0) { /* Don't return empty string */ - *s++ = '0'; - k = 0; + *st++ = '0'; + k = 0; } - *s = 0; + *st = 0; *decpt = k + 1; - if (rve) + if (rve != NULL) { - *rve = s; + *rve = st; } - return s0; + return st0; } diff --git a/libs/libc/stdio/lib_libdtoa.c b/libs/libc/stdio/lib_libdtoa.c index d7015acae53..1bab3656ad0 100644 --- a/libs/libc/stdio/lib_libdtoa.c +++ b/libs/libc/stdio/lib_libdtoa.c @@ -58,26 +58,20 @@ * Pre-processor Definitions ****************************************************************************/ -#define MAX_PREC 16 - #ifndef MIN -# define MIN(a,b) (a < b ? a : b) +# define MIN(a,b) (a < b ? a : b) #endif #ifndef MAX -# define MAX(a,b) (a > b ? a : b) +# define MAX(a,b) (a > b ? a : b) #endif -/* Use (almost) the maximim precision with %g format if no precision is - * specified. We do not use the full precision beause the least significant - * digits are probably garbage. - * - * REVISIT: This should be smarter. 15 digits is the maximum size of the - * number. The maximum precision is really 15 minus the number of digits - * in the integer part. +/* Use the maximim precision with %g format if no precision is specified. + * NOTE: This may result in numbers with precision that exceeds the + * precision of type double. */ -#define DOUBLE_PRECISON_MAX 13 /* vs 15 which is the maximum */ +#define DOUBLE_PRECISON_MAX 15 /* Use a default precision of 6 for the %f format if no precision is * specified. @@ -107,6 +101,24 @@ static void zeroes(FAR struct lib_outstream_s *obj, int nzeroes) } } +/**************************************************************************** + * Name: truncate_zeroes + * + * Description: + * Adjust the string length to eliminate zeros in the fractional part of + * the string. + * + ****************************************************************************/ + +static inline int truncate_zeroes(FAR char *digits, int expt, int numlen) +{ + for (; numlen > expt && digits[numlen - 1] == '0'; numlen--) + { + } + + return numlen; +} + /**************************************************************************** * Name: lib_dtoa_string * @@ -216,6 +228,28 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec, digits = __dtoa(value, 3, prec, &expt, &dsgn, &rve); numlen = rve - digits; + /* If we are going to truncate trailing zeros, then make sure we have not + * exceeded the precision of type double. + */ + + if (notrailing && numlen > DOUBLE_PRECISON_MAX) + { + /* Make sure there are fractional digits to truncate */ + + if (expt <= DOUBLE_PRECISON_MAX) + { + numlen = DOUBLE_PRECISON_MAX; + } + else + { + numlen = expt; + } + + /* Shortening the string probably now exposes some trailing zeroes */ + + numlen = truncate_zeroes(digits, expt, numlen); + } + /* Avoid precision error from missing trailing zeroes */ numlen = MAX(expt, numlen);