From owner-freebsd-hackers@FreeBSD.ORG Fri Mar 25 02:46:58 2011 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 1233) id 2AD1B1065670; Fri, 25 Mar 2011 02:46:58 +0000 (UTC) Date: Fri, 25 Mar 2011 02:46:58 +0000 From: Alexander Best To: freebsd-hackers@freebsd.org Message-ID: <20110325024658.GA19544@freebsd.org> References: <20110325002115.GA323@freebsd.org> <20110325015508.GA14565@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="CE+1k2dSO48ffgeK" Content-Disposition: inline In-Reply-To: <20110325015508.GA14565@freebsd.org> Subject: Re: Switching to [KMGTPE]i prefixes? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Mar 2011 02:46:58 -0000 --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--