From 626cd971624f0804d7b0ddada5168553c955aa64 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 14 Oct 2015 10:55:56 +0100 Subject: [PATCH] math/mptext.c: Reformat and refactor output functions. * Some layout fiddling. * Move some block-local variable declarations to the function head. * Split `digit_char' out as a separate function, seeing as it's used three times. * Rename the individual functions with a `write_...' prefix. A corresponding (more invasive) refactoring of the input function will have similar names, so avoid the obvious conflict. --- math/mptext.c | 141 +++++++++++++++++++++++----------------------------------- 1 file changed, 56 insertions(+), 85 deletions(-) diff --git a/math/mptext.c b/math/mptext.c index 5d4640ef..ddf50137 100644 --- a/math/mptext.c +++ b/math/mptext.c @@ -60,7 +60,7 @@ #define DEPTH (CHAR_BIT * sizeof(size_t) + 10) -/*----- Main code ---------------------------------------------------------*/ +/*----- Input -------------------------------------------------------------*/ /* --- @mp_read@ --- * * @@ -456,6 +456,8 @@ done: #undef f_ok } +/*----- Output ------------------------------------------------------------*/ + /* --- @mp_write@ --- * * * Arguments: @mp *m@ = pointer to a multi-precision integer @@ -468,6 +470,14 @@ done: * Use: Writes a large integer in textual form. */ +static int digit_char(int d, int radix) +{ + if (radix < 0) return (d); + else if (d < 10) return (d + '0'); + else if (d < 26) return (d - 10 + 'a'); + else return (d - 36 + 'A'); +} + /* --- Simple case --- * * * Use a fixed-sized buffer and single-precision arithmetic to pick off @@ -477,35 +487,23 @@ done: * enough real digits. */ -static int simple(mpw n, int radix, unsigned z, - const mptext_ops *ops, void *p) +static int write_simple(mpw n, int radix, unsigned z, + const mptext_ops *ops, void *p) { int rc = 0; char buf[64]; unsigned i = sizeof(buf); int rd = radix > 0 ? radix : -radix; + mpw x; do { - int ch; - mpw x; - - x = n % rd; - n /= rd; - if (radix < 0) - ch = x; - else if (x < 10) - ch = '0' + x; - else if (x < 36) /* Ascii specific */ - ch = 'a' + x - 10; - else - ch = 'A' + x - 36; - buf[--i] = ch; - if (z) - z--; + x = n % rd; n /= rd; + buf[--i] = digit_char(x, radix); + if (z) z--; } while (i && n); if (n) - rc = simple(n, radix, z, ops, p); + rc = write_simple(n, radix, z, ops, p); else { char zbuf[32]; memset(zbuf, (radix < 0) ? 0 : '0', sizeof(zbuf)); @@ -513,11 +511,9 @@ static int simple(mpw n, int radix, unsigned z, rc = ops->put(zbuf, sizeof(zbuf), p); z -= sizeof(zbuf); } - if (!rc && z) - rc = ops->put(zbuf, z, p); + if (!rc && z) rc = ops->put(zbuf, z, p); } - if (!rc) - rc = ops->put(buf + i, sizeof(buf) - i, p); + if (!rc) rc = ops->put(buf + i, sizeof(buf) - i, p); BURN(buf); return (rc); } @@ -530,29 +526,26 @@ static int simple(mpw n, int radix, unsigned z, * leading zeroes on the remainder part, because they're deeply significant. */ -static int complicated(mp *m, int radix, mp **pr, unsigned i, unsigned z, - const mptext_ops *ops, void *p) +static int write_complicated(mp *m, int radix, mp **pr, + unsigned i, unsigned z, + const mptext_ops *ops, void *p) { int rc = 0; mp *q = MP_NEW; unsigned d = 1 << i; if (MP_LEN(m) < 2) - return (simple(MP_LEN(m) ? m->v[0] : 0, radix, z, ops, p)); + return (write_simple(MP_LEN(m) ? m->v[0] : 0, radix, z, ops, p)); assert(i); mp_div(&q, &m, m, pr[i]); - if (MP_ZEROP(q)) - d = z; + if (MP_ZEROP(q)) d = z; else { - if (z > d) - z -= d; - else - z = 0; - rc = complicated(q, radix, pr, i - 1, z, ops, p); + if (z > d) z -= d; + else z = 0; + rc = write_complicated(q, radix, pr, i - 1, z, ops, p); } - if (!rc) - rc = complicated(m, radix, pr, i - 1, d, ops, p); + if (!rc) rc = write_complicated(m, radix, pr, i - 1, d, ops, p); mp_drop(q); return (rc); } @@ -562,7 +555,8 @@ static int complicated(mp *m, int radix, mp **pr, unsigned i, unsigned z, * Special case for binary output. Goes much faster. */ -static int binary(mp *m, int bit, int radix, const mptext_ops *ops, void *p) +static int write_binary(mp *m, int bit, int radix, + const mptext_ops *ops, void *p) { mpw *v; mpw a; @@ -573,15 +567,13 @@ static int binary(mp *m, int bit, int radix, const mptext_ops *ops, void *p) unsigned f = 0; char buf[8], *q; unsigned x; - int ch; #define f_out 1u /* --- Work out where to start --- */ n = mp_bits(m); - if (n % bit) - n += bit - (n % bit); + if (n % bit) n += bit - (n % bit); b = n % MPW_BITS; n /= MPW_BITS; @@ -604,43 +596,23 @@ static int binary(mp *m, int bit, int radix, const mptext_ops *ops, void *p) } else { x = a << (bit - b); b += MPW_BITS - bit; - if (v == m->v) - break; + if (v == m->v) break; a = *--v; - if (b < MPW_BITS) - x |= a >> b; + if (b < MPW_BITS) x |= a >> b; } x &= mask; - if (!x && !(f & f_out)) - continue; + if (!x && !(f & f_out)) continue; - if (radix < 0) - ch = x; - else if (x < 10) - ch = '0' + x; - else if (x < 36) - ch = 'a' + x - 10; /* Ascii specific */ - else - ch = 'A' + x - 36; - *q++ = ch; + *q++ = digit_char(x, radix); if (q >= buf + sizeof(buf)) { - if ((rc = ops->put(buf, sizeof(buf), p)) != 0) - goto done; + if ((rc = ops->put(buf, sizeof(buf), p)) != 0) goto done; q = buf; } f |= f_out; } x &= mask; - if (radix < 0) - ch = x; - else if (x < 10) - ch = '0' + x; - else if (x < 36) - ch = 'a' + x - 10; /* Ascii specific */ - else - ch = 'A' + x - 36; - *q++ = ch; + *q++ = digit_char(x, radix); rc = ops->put(buf, q - buf, p); done: @@ -655,6 +627,10 @@ done: int mp_write(mp *m, int radix, const mptext_ops *ops, void *p) { int rc; + mp *pr[DEPTH]; + size_t target; + unsigned i = 0; + mp *z; if (MP_EQ(m, MP_ZERO)) return (ops->put(radix > 0 ? "0" : "\0", 1, p)); @@ -677,27 +653,26 @@ int mp_write(mp *m, int radix, const mptext_ops *ops, void *p) if (MP_NEGP(m)) { assert(radix > 0); - if (ops->put("-", 1, p)) - return (EOF); + if (ops->put("-", 1, p)) return (EOF); m->f &= ~MP_NEG; } /* --- Handle binary radix --- */ switch (radix) { - case 2: case -2: return (binary(m, 1, radix, ops, p)); - case 4: case -4: return (binary(m, 2, radix, ops, p)); - case 8: case -8: return (binary(m, 3, radix, ops, p)); - case 16: case -16: return (binary(m, 4, radix, ops, p)); - case 32: case -32: return (binary(m, 5, radix, ops, p)); - case -64: return (binary(m, 6, radix, ops, p)); - case -128: return (binary(m, 7, radix, ops, p)); + case 2: case -2: return (write_binary(m, 1, radix, ops, p)); + case 4: case -4: return (write_binary(m, 2, radix, ops, p)); + case 8: case -8: return (write_binary(m, 3, radix, ops, p)); + case 16: case -16: return (write_binary(m, 4, radix, ops, p)); + case 32: case -32: return (write_binary(m, 5, radix, ops, p)); + case -64: return (write_binary(m, 6, radix, ops, p)); + case -128: return (write_binary(m, 7, radix, ops, p)); } /* --- If the number is small, do it the easy way --- */ if (MP_LEN(m) < 2) - rc = simple(MP_LEN(m) ? m->v[0] : 0, radix, 0, ops, p); + rc = write_simple(MP_LEN(m) ? m->v[0] : 0, radix, 0, ops, p); /* --- Use a clever algorithm --- * * @@ -709,10 +684,8 @@ int mp_write(mp *m, int radix, const mptext_ops *ops, void *p) */ else { - mp *pr[DEPTH]; - size_t target = (MP_LEN(m) + 1) / 2; - unsigned i = 0; - mp *z = mp_new(1, 0); + target = (MP_LEN(m) + 1) / 2; + z = mp_new(1, 0); /* --- Set up the exponent table --- */ @@ -721,19 +694,17 @@ int mp_write(mp *m, int radix, const mptext_ops *ops, void *p) for (;;) { assert(((void)"Number is too unimaginably huge", i < DEPTH)); pr[i++] = z; - if (MP_LEN(z) > target) - break; + if (MP_LEN(z) > target) break; z = mp_sqr(MP_NEW, z); } /* --- Write out the answer --- */ - rc = complicated(m, radix, pr, i - 1, 0, ops, p); + rc = write_complicated(m, radix, pr, i - 1, 0, ops, p); /* --- Tidy away the array --- */ - while (i > 0) - mp_drop(pr[--i]); + while (i > 0) mp_drop(pr[--i]); } /* --- Tidying up code --- */ -- 2.11.0