Re: [PATCH v15 03/12] lib: kstrtox: add kstrtoudec64() and kstrtodec64()

From: Andy Shevchenko

Date: Tue Jun 02 2026 - 17:00:24 EST


On Sun, May 31, 2026 at 09:30:46AM +0100, Rodrigo Alencar via B4 Relay wrote:
>
> Add helpers that parses decimal numbers into 64-bit number, i.e., decimal
> point numbers with pre-defined scale are parsed into a 64-bit value (fixed
> precision). After the decimal point, digits beyond the specified scale
> are ignored.

...

> +static int _kstrtoudec64(const char *s, unsigned int scale, u64 *res)
> +{
> + u64 _res = 0;
> + unsigned int rv_int, rv_frac;
> +
> + rv_int = _parse_integer(s, 10, &_res);
> + if (rv_int & KSTRTOX_OVERFLOW)
> + return -ERANGE;
> + s += rv_int;
> +
> + if (*s == '.')
> + s++; /* skip decimal point */
> +
> + rv_frac = _parse_integer_limit_init(s, 10, _res, &_res, scale);
> + if (rv_frac & KSTRTOX_OVERFLOW)
> + return -ERANGE;
> + s += rv_frac;

> + if (!rv_int && !rv_frac && !isdigit(*s))

Do we care about isdigit() here? Why?

> + return -EINVAL; /* no digits at all */

> + while (isdigit(*s)) /* truncate digits */
> + s++;

> + if (*s == '\n')
> + s++;
> + if (*s)
> + return -EINVAL;
> +
> + if (_res && (scale > (19 + rv_frac) || /* log10(2^64) = 19.26 */

It's better to make comment closer to the operand

if (_res && (scale > (19 + rv_frac) /* log10(2^64) = 19.26 */ ||

> + check_mul_overflow(_res, int_pow(10, scale - rv_frac), &_res)))

Can we deduplicate the scale - rv_frac?
I mean, would it be possible to do

if (_res && ((scale - rv_frac) > 19 /* log10(2^64) = 19.26 */ ||

without possible wraparound?

> + return -ERANGE;
> +
> + *res = _res;
> + return 0;
> +}

...

> +/**
> + * kstrtoudec64() - Convert a string to an unsigned 64-bit value that represents
> + * a scaled decimal number.
> + * @s: The start of the string. The string must be null-terminated, and may also
> + * include a single newline before its terminating null. The first character
> + * may also be a plus sign, but not a minus sign. Digits beyond the specified
> + * scale are ignored.
> + * @scale: The number of digits to the right of the decimal point. For example,
> + * a scale of 2 would mean the number is represented with two decimal places,
> + * so "123.45" would be represented as 12345.
> + * @res: Where to write the result of the conversion on success.

I believe it's better to leave short descriptions short and describe the
examples and other considerations here, in the description section.

All the same for the second one below.

> + * Return: 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
> + */

--
With Best Regards,
Andy Shevchenko