All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org>
To: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
	 Jonathan Cameron <jic23@kernel.org>,
	David Lechner <dlechner@baylibre.com>,
	 Andy Shevchenko <andy@kernel.org>,
	 Rodrigo Alencar <rodrigo.alencar@analog.com>
Subject: [PATCH RFC v2 1/4] lib: kstrtox: support E notation in kstrtoudec64() and kstrtodec64()
Date: Tue, 13 Oct 2026 10:36:44 -0300	[thread overview]
Message-ID: <20261013-e-notation-v2-1-d4adb5e193fc@analog.com> (raw)
In-Reply-To: <20261013-e-notation-v2-0-d4adb5e193fc@analog.com>

From: Rodrigo Alencar <rodrigo.alencar@analog.com>

Allow decimal strings to carry an exponent suffix, such as "2.7e10" or
"271828e-5", in kstrtoudec64() and kstrtodec64(). The exponent is added
to the requested scale to work out how many integer and fractional digits
are consumed. A negative effective exponent drops integer digits. Digits
beyond the resulting precision are truncated, as before.

The digits are now scanned first and the string termination is checked
before any conversion. A missing or malformed exponent ("1e", "1e+")
returns -EINVAL. An exponent that overflows when added to the scale, or
that makes the result exceed 64 bits, returns -ERANGE.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
 lib/kstrtox.c | 64 +++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index bac1c057e1b0..4755fc78a62c 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -397,39 +397,59 @@ EXPORT_SYMBOL(kstrtobool);
 
 static int _kstrtoudec64(const char *s, unsigned int scale, u64 *res)
 {
-	unsigned int rv_int, rv_frac;
+	const char *s_int, *s_frac;
+	int exp = 0, len_int = 0;
+	unsigned int rv;
 	u64 _res = 0;
+	int ret;
 
-	rv_int = _parse_integer(s, 10, &_res);
-	if (rv_int & KSTRTOX_OVERFLOW)
-		return -ERANGE;
-	s += rv_int;
+	s_int = s;
+	while (isdigit(*s)) {
+		s++;
+		len_int++;
+	}
 
 	if (*s == '.')
 		s++; /* skip decimal point */
 
-	rv_frac = _parse_integer(s, 10, &_res, scale, _res);
-	if (rv_frac & KSTRTOX_OVERFLOW)
+	s_frac = s;
+	while (isdigit(*s))
+		s++;
+
+	if (!len_int && s_frac == s)
+		return -EINVAL;
+
+	if (*s == 'e' || *s == 'E') { /* E Notation */
+		s++;
+		ret = kstrtoint(s, 10, &exp);
+		if (ret)
+			return ret;
+	} else { /* verify termination */
+		if (*s == '\n')
+			s++;
+		if (*s)
+			return -EINVAL;
+	}
+
+	if (check_add_overflow(exp, (int)scale, &exp))
 		return -ERANGE;
-	s += rv_frac;
 
-	/*
-	 * Check input beyond rv_int and rv_frac to cover cases like ".5" with
-	 * scale 0, which is considered a valid input, being parsed as 0.
-	 */
-	if (!rv_int && !rv_frac && !isdigit(*s))
-		return -EINVAL;
+	if (exp < 0) {
+		len_int = max(len_int + exp, 0);
+		exp = 0;
+	}
 
-	while (isdigit(*s)) /* truncate digits */
-		s++;
+	rv = _parse_integer(s_int, 10, &_res, len_int);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
 
-	if (*s == '\n')
-		s++;
-	if (*s)
-		return -EINVAL;
+	rv = _parse_integer(s_frac, 10, &_res, exp, _res);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
 
-	if (_res && ((scale - rv_frac) > 19 /* log10(2^64) = 19.26 */ ||
-		     check_mul_overflow(_res, int_pow(10, scale - rv_frac), &_res)))
+	exp -= rv;
+	if (_res && (exp > 19 /* log10(2^64) = 19.26 */ ||
+		     check_mul_overflow(_res, int_pow(10, exp), &_res)))
 		return -ERANGE;
 
 	*res = _res;

-- 
2.43.0



WARNING: multiple messages have this Message-ID (diff)
From: Rodrigo Alencar <rodrigo.alencar@analog.com>
To: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
	 Jonathan Cameron <jic23@kernel.org>,
	David Lechner <dlechner@baylibre.com>,
	 Andy Shevchenko <andy@kernel.org>,
	 Rodrigo Alencar <rodrigo.alencar@analog.com>
Subject: [PATCH RFC v2 1/4] lib: kstrtox: support E notation in kstrtoudec64() and kstrtodec64()
Date: Tue, 13 Oct 2026 10:36:44 -0300	[thread overview]
Message-ID: <20261013-e-notation-v2-1-d4adb5e193fc@analog.com> (raw)
In-Reply-To: <20261013-e-notation-v2-0-d4adb5e193fc@analog.com>

Allow decimal strings to carry an exponent suffix, such as "2.7e10" or
"271828e-5", in kstrtoudec64() and kstrtodec64(). The exponent is added
to the requested scale to work out how many integer and fractional digits
are consumed. A negative effective exponent drops integer digits. Digits
beyond the resulting precision are truncated, as before.

The digits are now scanned first and the string termination is checked
before any conversion. A missing or malformed exponent ("1e", "1e+")
returns -EINVAL. An exponent that overflows when added to the scale, or
that makes the result exceed 64 bits, returns -ERANGE.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
 lib/kstrtox.c | 64 +++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index bac1c057e1b0..4755fc78a62c 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -397,39 +397,59 @@ EXPORT_SYMBOL(kstrtobool);
 
 static int _kstrtoudec64(const char *s, unsigned int scale, u64 *res)
 {
-	unsigned int rv_int, rv_frac;
+	const char *s_int, *s_frac;
+	int exp = 0, len_int = 0;
+	unsigned int rv;
 	u64 _res = 0;
+	int ret;
 
-	rv_int = _parse_integer(s, 10, &_res);
-	if (rv_int & KSTRTOX_OVERFLOW)
-		return -ERANGE;
-	s += rv_int;
+	s_int = s;
+	while (isdigit(*s)) {
+		s++;
+		len_int++;
+	}
 
 	if (*s == '.')
 		s++; /* skip decimal point */
 
-	rv_frac = _parse_integer(s, 10, &_res, scale, _res);
-	if (rv_frac & KSTRTOX_OVERFLOW)
+	s_frac = s;
+	while (isdigit(*s))
+		s++;
+
+	if (!len_int && s_frac == s)
+		return -EINVAL;
+
+	if (*s == 'e' || *s == 'E') { /* E Notation */
+		s++;
+		ret = kstrtoint(s, 10, &exp);
+		if (ret)
+			return ret;
+	} else { /* verify termination */
+		if (*s == '\n')
+			s++;
+		if (*s)
+			return -EINVAL;
+	}
+
+	if (check_add_overflow(exp, (int)scale, &exp))
 		return -ERANGE;
-	s += rv_frac;
 
-	/*
-	 * Check input beyond rv_int and rv_frac to cover cases like ".5" with
-	 * scale 0, which is considered a valid input, being parsed as 0.
-	 */
-	if (!rv_int && !rv_frac && !isdigit(*s))
-		return -EINVAL;
+	if (exp < 0) {
+		len_int = max(len_int + exp, 0);
+		exp = 0;
+	}
 
-	while (isdigit(*s)) /* truncate digits */
-		s++;
+	rv = _parse_integer(s_int, 10, &_res, len_int);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
 
-	if (*s == '\n')
-		s++;
-	if (*s)
-		return -EINVAL;
+	rv = _parse_integer(s_frac, 10, &_res, exp, _res);
+	if (rv & KSTRTOX_OVERFLOW)
+		return -ERANGE;
 
-	if (_res && ((scale - rv_frac) > 19 /* log10(2^64) = 19.26 */ ||
-		     check_mul_overflow(_res, int_pow(10, scale - rv_frac), &_res)))
+	exp -= rv;
+	if (_res && (exp > 19 /* log10(2^64) = 19.26 */ ||
+		     check_mul_overflow(_res, int_pow(10, exp), &_res)))
 		return -ERANGE;
 
 	*res = _res;

-- 
2.43.0


  reply	other threads:[~2026-10-13 13:36 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 13:36 [PATCH RFC v2 0/4] Add E notation support to kstrtodec64() and IIO sysfs writes Rodrigo Alencar via B4 Relay
2026-10-13 13:36 ` Rodrigo Alencar
2026-10-13 13:36 ` Rodrigo Alencar via B4 Relay [this message]
2026-10-13 13:36   ` [PATCH RFC v2 1/4] lib: kstrtox: support E notation in kstrtoudec64() and kstrtodec64() Rodrigo Alencar
2026-10-13 18:48   ` Andy Shevchenko
2026-10-13 13:36 ` [PATCH RFC v2 2/4] lib: test-kstrtox: add E notation tests for kstrto[u]dec64() Rodrigo Alencar via B4 Relay
2026-10-13 13:36   ` Rodrigo Alencar
2026-10-13 18:49   ` Andy Shevchenko
2026-10-13 13:36 ` [PATCH RFC v2 3/4] iio: core: use kstrtodec64() to parse fixed-point values Rodrigo Alencar via B4 Relay
2026-10-13 13:36   ` Rodrigo Alencar
2026-10-13 19:08   ` Andy Shevchenko
2026-10-13 13:36 ` [PATCH RFC v2 4/4] iio: test: add kunit tests for channel info writes Rodrigo Alencar via B4 Relay
2026-10-13 13:36   ` Rodrigo Alencar
2026-10-13 19:10   ` Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261013-e-notation-v2-1-d4adb5e193fc@analog.com \
    --to=devnull+rodrigo.alencar.analog.com@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=andy@kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rodrigo.alencar@analog.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.