summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2011-04-12 22:48:03 +0000
committerdelphij <delphij@FreeBSD.org>2011-04-12 22:48:03 +0000
commitc14cd58282c1241f10c3b38c4ca228eff76f0249 (patch)
tree1d297847768a266148a22df81c1c1919c53aacf6 /lib
parent2092a06579f29873b4c1f7e4a294dfc71e455844 (diff)
downloadFreeBSD-src-c14cd58282c1241f10c3b38c4ca228eff76f0249.zip
FreeBSD-src-c14cd58282c1241f10c3b38c4ca228eff76f0249.tar.gz
Add support for IEE/IEC (and now also SI) power of two notions of
prefixes (Ki, Mi, Gi...) for humanize_number(3). Note that applications has to pass HN_IEC_PREFIXES to use this feature for backward compatibility reasons. Reviewed by: arundel MFC after: 2 weeks
Diffstat (limited to 'lib')
-rw-r--r--lib/libutil/humanize_number.363
-rw-r--r--lib/libutil/humanize_number.c51
-rw-r--r--lib/libutil/libutil.h2
3 files changed, 89 insertions, 27 deletions
diff --git a/lib/libutil/humanize_number.3 b/lib/libutil/humanize_number.3
index 82925ba..32df6f8 100644
--- a/lib/libutil/humanize_number.3
+++ b/lib/libutil/humanize_number.3
@@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 25, 2004
+.Dd Apr 12, 2011
.Dt HUMANIZE_NUMBER 3
.Os
.Sh NAME
@@ -68,17 +68,24 @@ then divide
by 1024 until it will.
In this case, prefix
.Fa suffix
-with the appropriate SI designator.
+with the appropriate designator.
The
.Fn humanize_number
-function
-follows the traditional computer science conventions rather than the proposed
-SI power of two convention.
+function follows the traditional computer science conventions by
+default, rather than the IEE/IEC (and now also SI) power of two
+convention or the power of ten notion.
+This behaviour however can be altered by specifying the
+.Dv HN_DIVISOR_1000
+and
+.Dv HN_IEC_PREFIXES
+flags.
.Pp
-The prefixes are:
+The traditional
+.Pq 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 (note) 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 +93,20 @@ The prefixes are:
.It Li E Ta No exa Ta 1152921504606846976 Ta 1000000000000000000
.El
.Pp
+Note:
+An uppercase K indicates a power of two, a lowercase k a power of ten.
+.Pp
+The IEE/IEC (and now also SI) power of two 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
@@ -94,7 +115,12 @@ in order to ensure a useful result is generated into
.Fa buf .
To use a specific prefix, specify this as
.Fa scale
-(multiplier = 1024 ^ scale).
+.Po multiplier = 1024 ^ scale;
+when
+.Dv HN_DIVISOR_1000
+is specified,
+multiplier = 1000 ^ scale
+.Pc .
This cannot be combined with any of the
.Fa scale
flags below.
@@ -127,6 +153,11 @@ Use
Divide
.Fa number
with 1000 instead of 1024.
+.It Dv HN_IEC_PREFIXES
+Use the IEE/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
@@ -141,6 +172,18 @@ If
is specified, the prefix index number will be returned instead.
.Sh SEE ALSO
.Xr expand_number 3
+.Sh STANDARDS
+The
+.Dv HN_DIVISOR_1000
+and
+.Dv HN_IEC_PREFIXES
+flags
+conform to
+.Tn ISO/IEC
+Std\~80000-13:2008
+and
+.Tn IEEE
+Std\~1541-2002.
.Sh HISTORY
The
.Fn humanize_number
@@ -148,3 +191,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..024bc6b 100644
--- a/lib/libutil/humanize_number.c
+++ b/lib/libutil/humanize_number.c
@@ -42,45 +42,58 @@ __FBSDID("$FreeBSD$");
#include <locale.h>
#include <libutil.h>
+static const int maxscale = 7;
+
int
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, s1, s2, sign;
int64_t divisor, max;
size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
assert(scale >= 0);
+ assert(scale < maxscale || (((scale & (HN_AUTOSCALE | HN_GETSCALE)) != 0)));
+ assert(!((flags & HN_DIVISOR_1000) && (flags & HN_IEC_PREFIXES)));
remainder = 0;
- if (flags & HN_DIVISOR_1000) {
- /* SI for decimal multiplies */
- divisor = 1000;
- 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) {
+ baselen = 2;
/*
- * binary multiplies
- * XXX IEC 60027-2 recommends Ki, Mi, Gi...
+ * Use the prefixes for power of two recommended by
+ * the International Electrotechnical Commission
+ * (IEC) in IEC 80000-3 (i.e. Ki, Mi, Gi...).
+ *
+ * HN_IEC_PREFIXES implies a divisor of 1024 here
+ * (use of HN_DIVISOR_1000 would have triggered
+ * an assertion earlier).
*/
divisor = 1024;
if (flags & HN_B)
- prefixes = "B\0K\0M\0G\0T\0P\0E";
+ prefixes = "B\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
+ else
+ prefixes = "\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
+ } else {
+ baselen = 1;
+ if (flags & HN_DIVISOR_1000)
+ divisor = 1000;
+ else
+ divisor = 1024;
+
+ if (flags & HN_B)
+ prefixes = "B\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
else
- prefixes = "\0\0K\0M\0G\0T\0P\0E";
+ prefixes = "\0\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
}
-#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
- maxscale = 7;
+#define SCALE2PREFIX(scale) (&prefixes[(scale) * 3])
- if (scale >= maxscale &&
- (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
+ if (scale < 0 || (scale >= maxscale &&
+ (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0))
return (-1);
if (buf == NULL || suffix == NULL)
@@ -91,10 +104,10 @@ humanize_number(char *buf, size_t len, int64_t quotient,
if (quotient < 0) {
sign = -1;
quotient = -quotient;
- baselen = 3; /* sign, digit, prefix */
+ baselen += 2; /* sign, digit */
} else {
sign = 1;
- baselen = 2; /* digit, prefix */
+ baselen += 1; /* digit */
}
if (flags & HN_NOSPACE)
sep = "";
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index 66104e9..5dca37c 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -220,7 +220,9 @@ __END_DECLS
#define HN_NOSPACE 0x02
#define HN_B 0x04
#define HN_DIVISOR_1000 0x08
+#define HN_IEC_PREFIXES 0x10
+/* maxscale = 0x07 */
#define HN_GETSCALE 0x10
#define HN_AUTOSCALE 0x20
OpenPOWER on IntegriCloud