Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Mar 2011 02:46:58 +0000
From:      Alexander Best <arundel@freebsd.org>
To:        freebsd-hackers@freebsd.org
Subject:   Re: Switching to [KMGTPE]i prefixes?
Message-ID:  <20110325024658.GA19544@freebsd.org>
In-Reply-To: <20110325015508.GA14565@freebsd.org>
References:  <20110325002115.GA323@freebsd.org> <20110325015508.GA14565@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--CE+1k2dSO48ffgeK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

here is a revised patch. it also includes the necessary changes to the
humanize_number(3) man page.

cheers.
alex

-- 
a13x

--CE+1k2dSO48ffgeK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="IEC_80000_13.diff"

diff --git a/lib/libutil/humanize_number.3 b/lib/libutil/humanize_number.3
index 82925ba..841da3f 100644
--- a/lib/libutil/humanize_number.3
+++ b/lib/libutil/humanize_number.3
@@ -68,17 +68,22 @@ then divide
 by 1024 until it will.
 In this case, prefix
 .Fa suffix
-with the appropriate SI designator.
+with the appropriate SI (or IEC) designator.
 The
 .Fn humanize_number
 function
-follows the traditional computer science conventions rather than the proposed
-SI power of two convention.
+follows the traditional computer science conventions by default rather than the proposed
+IEC power of two convention or the power of ten notion.
+This behaviour however can be altered by the
+.Dv HN_DIVISOR_1000
+and
+.Dv HN_IEC_PREFIXES
+flags.
 .Pp
-The prefixes are:
+The default prefixes are:
 .Bl -column "Prefix" "Description" "1000000000000000000" -offset indent
 .It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier" Ta Sy "Multiplier 1000x"
-.It Li k Ta No kilo Ta 1024 Ta 1000
+.It Li * Ta No kilo Ta 1024 Ta 1000
 .It Li M Ta No mega Ta 1048576 Ta 1000000
 .It Li G Ta No giga Ta 1073741824 Ta 1000000000
 .It Li T Ta No tera Ta 1099511627776 Ta 1000000000000
@@ -86,6 +91,19 @@ The prefixes are:
 .It Li E Ta No exa Ta 1152921504606846976 Ta 1000000000000000000
 .El
 .Pp
+* An uppercase K indicates a power of two, a lowercase k a power of ten.
+.Pp
+The IEC power of two (IEC 80000-13) prefixes are:
+.Bl -column "Prefix" "Description" "1000000000000000000" -offset indent
+.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
+.It Li Ki Ta No kibi Ta 1024
+.It Li Mi Ta No mebi Ta 1048576
+.It Li Gi Ta No gibi Ta 1073741824
+.It Li Ti Ta No tebi Ta 1099511627776
+.It Li Pi Ta No pebi Ta 1125899906842624
+.It Li Ei Ta No exbi Ta 1152921504606846976
+.El
+.Pp
 The
 .Fa len
 argument must be at least 4 plus the length of
@@ -127,6 +145,11 @@ Use
 Divide
 .Fa number
 with 1000 instead of 1024.
+.It Dv HN_IEC_PREFIXES
+Use the IEC notion of prefixes (Ki, Mi, Gi...).
+This flag has no effect when
+.Dv HN_DIVISOR_1000
+is also specified.
 .El
 .Sh RETURN VALUES
 The
@@ -148,3 +171,7 @@ function first appeared in
 .Nx 2.0
 and then in
 .Fx 5.3 .
+The
+.Dv HN_IEC_PREFIXES
+flag was introduced in
+.Fx 9.0 .
diff --git a/lib/libutil/humanize_number.c b/lib/libutil/humanize_number.c
index 75bcb46..efa06cb 100644
--- a/lib/libutil/humanize_number.c
+++ b/lib/libutil/humanize_number.c
@@ -47,7 +47,7 @@ humanize_number(char *buf, size_t len, int64_t quotient,
     const char *suffix, int scale, int flags)
 {
 	const char *prefixes, *sep;
-	int	i, r, remainder, maxscale, s1, s2, sign;
+	int	i, r, remainder, maxscale, s1, s2, shift, sign;
 	int64_t	divisor, max;
 	size_t	baselen;
 
@@ -57,26 +57,41 @@ humanize_number(char *buf, size_t len, int64_t quotient,
 
 	remainder = 0;
 
+	/*
+	 * With HN_DIVISOR_1000 defined, SI prefixes for decimal multiplies
+	 * are used. Without this flag, the raditional power of two prefixes
+	 * are used. If however HN_IEC_PREFIXES is defined, the power of
+	 * two prefixes recommended by the International Electrotechnical
+	 * Commission (IEC) in IEC 80000-3 (superseeding IEC 60027-2)
+	 * (i.e. Ki, Mi, Gi...) are used.
+	 *
+	 * Please note that HN_DIVISOR_1000 takes priority over HN_IEC_PREFIXES.
+	 * The default behavior is to use the traditional power of two prefixes.
+	 */
 	if (flags & HN_DIVISOR_1000) {
-		/* SI for decimal multiplies */
 		divisor = 1000;
+		shift = 1;
 		if (flags & HN_B)
 			prefixes = "B\0k\0M\0G\0T\0P\0E";
 		else
 			prefixes = "\0\0k\0M\0G\0T\0P\0E";
+	} else if (flags & HN_IEC_PREFIXES) {
+		divisor = 1024;
+		shift = 2;
+		if (flags & HN_B)
+			prefixes = "B\0\0\0Ki\0\0Mi\0\0Gi\0\0Ti\0\0Pi\0\0Ei";
+		else
+			prefixes = "\0\0\0\0Ki\0\0Mi\0\0Gi\0\0Ti\0\0Pi\0\0Ei";
 	} else {
-		/*
-		 * binary multiplies
-		 * XXX IEC 60027-2 recommends Ki, Mi, Gi...
-		 */
 		divisor = 1024;
+		shift = 1;
 		if (flags & HN_B)
 			prefixes = "B\0K\0M\0G\0T\0P\0E";
 		else
 			prefixes = "\0\0K\0M\0G\0T\0P\0E";
 	}
 
-#define	SCALE2PREFIX(scale)	(&prefixes[(scale) << 1])
+#define	SCALE2PREFIX(scale)	(&prefixes[(scale) << shift])
 	maxscale = 7;
 
 	if (scale >= maxscale &&
@@ -102,6 +117,10 @@ humanize_number(char *buf, size_t len, int64_t quotient,
 		sep = " ";
 		baselen++;
 	}
+	if (flags & HN_IEC_PREFIXES) {
+		baselen ++;
+		len ++;
+	}
 	baselen += strlen(suffix);
 
 	/* Check if enough room for `x y' + suffix + `\0' */
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index 66104e9..295a8d3 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -220,6 +220,7 @@ __END_DECLS
 #define HN_NOSPACE		0x02
 #define HN_B			0x04
 #define HN_DIVISOR_1000		0x08
+#define HN_IEC_PREFIXES		0x0f
 
 #define HN_GETSCALE		0x10
 #define HN_AUTOSCALE		0x20

--CE+1k2dSO48ffgeK--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110325024658.GA19544>