From bbca1c106ce5728cfabff04d32055c2122489457 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 9 Jul 2025 10:36:04 -0700 Subject: [PATCH] factor: speed up converting strings to uuint MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/factor.c: Do not include c-ctype.h. (strtouuint): Don’t bother generating a number on error; just return a strtol_error value other than LONGINT_OK. Speed up overflow checking. --- src/factor.c | 55 +++++++++++++--------------------------------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/src/factor.c b/src/factor.c index 6fe900af31..134c092f84 100644 --- a/src/factor.c +++ b/src/factor.c @@ -84,7 +84,6 @@ #include "system.h" #include "assure.h" -#include "c-ctype.h" #include "full-write.h" #include "quote.h" #include "readtokens.h" @@ -1626,61 +1625,35 @@ mp_factor (mpz_t t) return factors; } -/* Convert to *U the value represnted by S. - Return an error indicator. */ +/* Convert to *U the value represented by S, and return LONGINT_OK. + However, on error simply return a value other than LONGINT_OK. */ static strtol_error strtouuint (uuint *u, char const *s) { - int lo_carry; - mp_limb_t hi = 0, lo = 0; + mp_limb_t hi = 0, lo = *s++ - '0'; - strtol_error err = LONGINT_INVALID; + if (UNLIKELY (9 < lo)) + return LONGINT_INVALID; - /* Initial scan for invalid digits. */ - char const *p = s; - for (;;) - { - unsigned char c = *p++; - if (c == 0) - break; - - if (UNLIKELY (!c_isdigit (c))) - { - err = LONGINT_INVALID; - break; - } - - err = LONGINT_OK; /* we've seen at least one valid digit */ - } - - while (err == LONGINT_OK) + for (; LIKELY (0 <= *s - '0' && *s - '0' <= 9); s++) { - unsigned char c = *s++; - if (c == 0) - break; - - c -= '0'; - if (UNLIKELY (ckd_mul (&hi, hi, 10))) - { - err = LONGINT_OVERFLOW; - break; - } + return LONGINT_OVERFLOW; - lo_carry = (lo >> (W_TYPE_SIZE - 3)) + (lo >> (W_TYPE_SIZE - 1)); + int lo_carry = (lo >> (W_TYPE_SIZE - 3)) + (lo >> (W_TYPE_SIZE - 1)); lo_carry += 10 * lo < 2 * lo; lo = 10 * lo; - lo_carry += ckd_add (&lo, lo, c); + lo_carry += ckd_add (&lo, lo, *s - '0'); if (UNLIKELY (ckd_add (&hi, hi, lo_carry))) - { - err = LONGINT_OVERFLOW; - break; - } + return LONGINT_OVERFLOW; } + if (UNLIKELY (*s)) + return LONGINT_INVALID; + *u = make_uuint (hi, lo); - return err; + return LONGINT_OK; } /* FACTOR_PIPE_BUF is chosen to give good performance, -- 2.47.3