NetBSD Problem Report #60635
From www@netbsd.org Sun Aug 23 16:35:19 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "YR2" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 690731A923B
for <gnats-bugs@gnats.NetBSD.org>; Sun, 23 Aug 2026 16:35:19 +0000 (UTC)
Message-Id: <20260823163517.D0DD91A923C@mollari.NetBSD.org>
Date: Sun, 23 Aug 2026 16:35:17 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: humanize_number(3): exa/exbi issues
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>
>Number: 60635
>Category: lib
>Synopsis: humanize_number(3): exa/exbi issues
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Aug 23 16:40:01 +0000 2026
>Last-Modified: Sun Aug 23 23:00:02 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10, 9, ...
>Organization:
The NetBSD Countation, SInc.
>Environment:
>Description:
1. humanize_number() doesn't have any options for producing IEC
byte units like KiB/GiB and always uses the nonstandard
binary `SI' prefixes (or JEDEC units).
Even if you find pronouncing kitty-kibble-bytes^Wkibibytes
goofy, we should have a way to produce the IEC units,
especially in contexts where binary vs decimal is not clear
(like packet rates, which are often in measured in
decimal-powers of bits or packets per second, while traffic
is often measured in binary-powers of bytes per second).
2. humanize_number() apparently can't handle single-digit
numbers of EiB.
>How-To-Repeat:
$ cat h.c
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
static void
show(int64_t x)
{
char buf[5] = "";
int result;
result = humanize_number(buf, sizeof(buf), x, "", HN_AUTOSCALE, 0);
printf("%"PRId64": [%d] -> \"%s\"\n", x, result, buf);
}
int
main(void)
{
show(1);
show(1024LL*1024);
show(1024LL*1024*1024);
show(1024LL*1024*1024*1024);
show(1024LL*1024*1024*1024*1024);
show(1024LL*1024*1024*1024*1024*1024);
fflush(stdout);
return ferror(stdout);
}
$ make h
cc -O2 -o h h.c
$ ./h
1: [2] -> "1 "
1048576: [3] -> "1 M"
1073741824: [3] -> "1 G"
1099511627776: [3] -> "1 T"
1125899906842624: [3] -> "1 P"
1152921504606846976: [-1] -> ""
Expected output:
1: [2] -> "1 "
1048576: [3] -> "1 M"
1073741824: [3] -> "1 G"
1099511627776: [3] -> "1 T"
1125899906842624: [3] -> "1 P"
1152921504606846976: [3] -> "1 E"
>Fix:
Yes, please!
>Audit-Trail:
From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@netbsd.org, netbsd-bugs@netbsd.org
Cc:
Subject: Re: lib/60635: humanize_number(3): exa/exbi issues
Date: Sun, 23 Aug 2026 17:39:25 +0000
This is a multi-part message in MIME format.
--=_aD0stfJJ+WVg8+9bTfy4bTTT5i9m1xYu
--=_aD0stfJJ+WVg8+9bTfy4bTTT5i9m1xYu
Content-Type: text/plain; charset="ISO-8859-1"; name="pr60635-humanizeiec"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="pr60635-humanizeiec.patch"
# HG changeset patch
# User Taylor R Campbell <riastradh@NetBSD.org>
# Date 1787506011 0
# Sun Aug 23 17:26:51 2026 +0000
# Branch trunk
# Node ID cc8c7b6b7bd389ee5f3db6fdd197869e8577a0cd
# Parent 6f8d3c18f5e5266c57e1b8b3736224c0146f1726
# EXP-Topic riastradh-pr59411-prgrowingnowaitcleanup
humanize_number(3): New option HN_IEC for IEC prefixes.
PR lib/60635: humanize_number(3): exa/exbi issues
diff -r 6f8d3c18f5e5 -r cc8c7b6b7bd3 lib/libc/gen/humanize_number.3
--- a/lib/libc/gen/humanize_number.3 Sun Aug 23 16:54:15 2026 +0000
+++ b/lib/libc/gen/humanize_number.3 Sun Aug 23 17:26:51 2026 +0000
@@ -61,20 +61,52 @@ would be too long to fit into
.Fa buffer ,
then repeatedly divide
.Fa number
-by 1024 until it will fit.
+by a base, either 1024 (default) or 1000 (decimal, with
+.Dv HN_DIVISOR_1000 ) ,
+until it will fit.
In this case, prefix
.Fa suffix
-with the appropriate SI designator.
+with the corresponding scale designator.
+.Pp
+For the default binary base (1024), the prefixes are:
+.Bl -column "Prefix" "IEC" "Name" "Multiplier" -offset indent
+.It Sy "Prefix" Ta Sy "IEC" Ta Sy "Name" Ta Sy "Multiplier"
+.It K Ki kibi 1,024
+.It M Mi mebi 1,048,576
+.It G Gi gibi 1,073,741,824
+.It T Ti tebi 1,099,511,627,776
+.It P Pi pebi 1,125,899,906,842,624
+.It E Ei exbi 1,152,921,504,606,846,976
+.El
.Pp
-The prefixes are:
-.Bl -column "Prefix" "Description" "Multiplier" -offset indent
-.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
-.It k kilo 1024
-.It M mega 1048576
-.It G giga 1073741824
-.It T tera 1099511627776
-.It P peta 1125899906842624
-.It E exa 1152921504606846976
+The nonstandard
+.Dq Tn SI
+or
+.Tn JEDEC Ns No - Ns style
+prefixes
+.Dq K ,
+.Dq M ,
+etc., are chosen by default.
+The
+.Tn IEC
+prefixes
+.Dq Ki ,
+.Dq Mi ,
+etc., are chosen by the
+.Dv HN_IEC
+option.
+.Pp
+For the decimal base (1000, chosen by
+.Dv HN_DIVISOR_1000 ) ,
+the SI prefixes are:
+.Bl -column "Prefix" "Name" "Multiplier" -offset indent
+.It Sy "Prefix" Ta Sy "Name" Ta Sy "Multiplier"
+.It k kilo 1,000
+.It M mega 1,000,000
+.It G giga 1,000,000,000
+.It T tera 1,000,000,000,000
+.It P peta 1,000,000,000,000,000
+.It E exa 1,000,000,000,000,000,000
.El
.Pp
.Fa len
@@ -123,6 +155,17 @@ Divide
.Fa number
with 1000 instead of 1024.
That is, use decimal scaling instead of binary.
+.Pp
+Exclusive with
+.Dv HN_IEC .
+.It Dv HN_IEC
+Use IEC prefixes
+.Dq Ki ,
+.Dq Mi ,
+etc.
+.Pp
+Exclusive with
+.Dv HN_DIVISOR_1000 .
.El
.Pp
To generate the shortest meaningful value,
diff -r 6f8d3c18f5e5 -r cc8c7b6b7bd3 lib/libc/gen/humanize_number.c
--- a/lib/libc/gen/humanize_number.c Sun Aug 23 16:54:15 2026 +0000
+++ b/lib/libc/gen/humanize_number.c Sun Aug 23 17:26:51 2026 +0000
@@ -52,9 +52,12 @@ humanize_number(char *buf, size_t len, i
int64_t divisor, max, post =3D 1;
size_t baselen;
int maxscale;
+ int prefixbytes =3D 1;
=20
_DIAGASSERT(buf !=3D NULL);
_DIAGASSERT(scale >=3D 0);
+ _DIAGASSERT((flags & (HN_DIVISOR_1000|HN_IEC)) !=3D
+ (HN_DIVISOR_1000|HN_IEC));
=20
if (suffix =3D=3D NULL)
suffix =3D "";
@@ -68,17 +71,31 @@ humanize_number(char *buf, size_t len, i
prefixes =3D "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
- * binary multiplies
- * XXX IEC 60027-2 recommends Ki, Mi, Gi...
+ * binary multiplies with `SI'/JEDEC-style or IEC
+ * prefixes
*/
divisor =3D 1024;
- if (flags & HN_B)
+ switch (flags & (HN_B|HN_IEC)) {
+ case HN_B:
prefixes =3D "B\0K\0M\0G\0T\0P\0E";
- else
+ break;
+ case 0:
prefixes =3D "\0\0K\0M\0G\0T\0P\0E";
+ break;
+ case HN_B|HN_IEC:
+ prefixes =3D "B\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
+ prefixbytes =3D 2;
+ break;
+ case HN_IEC:
+ prefixes =3D "\0\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
+ prefixbytes =3D 2;
+ break;
+ default:
+ __unreachable();
+ }
}
=20
-#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
+#define SCALE2PREFIX(scale) (&prefixes[(scale) * (prefixbytes + 1)])
maxscale =3D 6;
=20
if (scale < 0 || (scale > maxscale &&
diff -r 6f8d3c18f5e5 -r cc8c7b6b7bd3 tests/lib/libc/gen/t_humanize_number.c
--- a/tests/lib/libc/gen/t_humanize_number.c Sun Aug 23 16:54:15 2026 +0000
+++ b/tests/lib/libc/gen/t_humanize_number.c Sun Aug 23 17:26:51 2026 +0000
@@ -112,6 +112,32 @@ const struct hnopts {
NULL },
{ 4, 1024LL*1024*1024*1024*1024*1024, "", HN_AUTOSCALE, HN_B, 3, "1 E",
"PR lib/60635: humanize_number(3): exa/exbi issues" },
+
+ { 5, 1, "", HN_AUTOSCALE, HN_IEC, 2, "1 ", NULL },
+ { 5, 1024LL, "", HN_AUTOSCALE, HN_IEC, 4, "1 Ki", NULL },
+ { 5, 1024LL*1024, "", HN_AUTOSCALE, HN_IEC, 4, "1 Mi", NULL },
+ { 5, 1024LL*1024*1024, "", HN_AUTOSCALE, HN_IEC, 4, "1 Gi", NULL },
+ { 5, 1024LL*1024*1024*1024, "", HN_AUTOSCALE, HN_IEC, 4, "1 Ti",
+ NULL },
+ { 5, 1024LL*1024*1024*1024*1024, "", HN_AUTOSCALE, HN_IEC, 4, "1 Pi",
+ NULL },
+ { 5, 1024LL*1024*1024*1024*1024*1024, "", HN_AUTOSCALE,HN_IEC, 4,
+ "1 Ei",
+ "PR lib/60635: humanize_number(3): exa/exbi issues" },
+
+ { 5, 1, "", HN_AUTOSCALE, HN_IEC|HN_B, 3, "1 B", NULL },
+ { 5, 1024LL, "", HN_AUTOSCALE, HN_IEC|HN_B, 4, "1 Ki", NULL },
+ { 5, 1024LL*1024, "", HN_AUTOSCALE, HN_IEC|HN_B, 4, "1 Mi", NULL },
+ { 5, 1024LL*1024*1024, "", HN_AUTOSCALE, HN_IEC|HN_B, 4, "1 Gi",
+ NULL },
+ { 5, 1024LL*1024*1024*1024, "", HN_AUTOSCALE, HN_IEC|HN_B, 4, "1 Ti",
+ NULL },
+ { 5, 1024LL*1024*1024*1024*1024, "", HN_AUTOSCALE, HN_IEC|HN_B, 4,
+ "1 Pi",
+ NULL },
+ { 5, 1024LL*1024*1024*1024*1024*1024, "", HN_AUTOSCALE, HN_IEC|HN_B, 4,
+ "1 Ei",
+ "PR lib/60635: humanize_number(3): exa/exbi issues" },
};
=20
struct hnflags {
--=_aD0stfJJ+WVg8+9bTfy4bTTT5i9m1xYu--
From: Robert Elz <kre@munnari.OZ.AU>
To: Taylor R Campbell <riastradh@NetBSD.org>
Cc: gnats-bugs@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: lib/60635: humanize_number(3): exa/exbi issues
Date: Mon, 24 Aug 2026 03:43:09 +0700
Your patch seems to be missing the change needed (in <stdlib.h> presumably,
though putting humanize_number() in there seems to be a bit of probably
over-wishful thinking in the first place) to define HN_IEC, - and nor is
there any mention of what might need (or perhaps should need) to happen
to dehumanize_number() to remain even semi-compatible with what
humanize_number() will be able to produce - or even if that is possible,
given its interface API.
kre
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60635 CVS commit: src/lib/libc
Date: Sun, 23 Aug 2026 22:56:28 +0000
Module Name: src
Committed By: riastradh
Date: Sun Aug 23 22:56:28 UTC 2026
Modified Files:
src/lib/libc: shlib_version
Log Message:
libc: Suggest another major bump task.
Prompted by noting that stdlib.h and libc are maybe not the right
place for this API in:
PR lib/60635: humanize_number(3): exa/exbi issues
To generate a diff of this commit:
cvs rdiff -u -r1.300 -r1.301 src/lib/libc/shlib_version
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.