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.

NetBSD Home
NetBSD PR Database Search

(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.