This piece of code will render data storage capacity numbers in human-friendly format, with rounding, similar to "ls -lh", "du -h" etc.
sub human_size { my $val = shift; # 2**10 (binary) multiplier by default my $multiplier = @_ ? shift : 1024; my $magnitude = 0; my @suffixes = qw/B KB MB GB TB PB EB/; my $rval; while (($rval = sprintf("%.2f",$val)) >= $multiplier) { $val /= $multiplier; $magnitude++; } # Use Perl's numeric conversion to remove trailing zeros # in the fraction and the decimal point if unnecessary $rval = 0 + $rval; if(wantarray) { ($rval, $magnitude, $suffixes[$magnitude]); } else { "$rval $suffixes[$magnitude]"; } } ## ## Example code below ## # read value from the command line my $val = shift; # Scalar context example printf "Size: %s\n", scalar human_size($val); # List context example my @fancy_suffixes = map "${_}bytes", '', qw/kilo mega giga tera peta +exa/; my ($hval, $mag, $sfx) = human_size($val, 10**3); $hval .= ' decimal' if $mag; # omit for values < 1KB $hval = "$hval $fancy_suffixes[$mag] ($sfx)"; print "Size: $hval\n";

Replies are listed 'Best First'.
Re: "Human" pretty-printer for data capacity
by andreas1234567 (Vicar) on Oct 03, 2007 at 09:03 UTC
    Hi calin,

    Thank you for sharing your code. There is a related module Number::Bytes::Human:

    $ perl -l use strict; use warnings; use Number::Bytes::Human qw(format_bytes); print format_bytes(1E9, bs => 1000); print format_bytes(1E9, bs => 1024); __END__ 1.0G 954M
    --
    Andreas
Re: "Human" pretty-printer for data capacity
by grinder (Bishop) on Oct 03, 2007 at 10:47 UTC

    New IEC prefixes for multiples of 1024 were introduced in 1998 or so, get with the times man :)

    While you're at it, you may as well toss in the zetta- and yotta- prefixes...

    my @suffixes = qw/B KiB MiB GiB TiB PiB EiB ZiB YiB/;

    • another intruder with the mooring in the heart of the Perl

      I know about these prefixes but I chose not to put them in the code because a) nobody seems to be using them and b) the code is intentionally ambiguous.

      By the way the format used in the GNU utils is only the letter without 'B' suffix and no space like this: '456', '21.3K', '16G' etc.