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
This commit is contained in:
parent
e94d5ad227
commit
7d14df1a2d
@ -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 .
|
||||
|
@ -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\0K\0M\0G\0T\0P\0E";
|
||||
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\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 = "";
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user