Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert a number to its multiple form in Perl?

Do you know an easy and straight-forward method/sub/module which allows me to convert a number (say 1234567.89) to an easily readable form - something like 1.23M?

Right now I can do this by making several comparisons, but I'm not happy with my method:

if($bytes > 1000000000){ 
   $bytes = ( sprintf( "%0.2f", $bytes/1000000000 )). " Gb/s";                   
}
elsif ($bytes > 1000000){       
   $bytes = ( sprintf( "%0.2f", $bytes/1000000 )). " Mb/s"; 
}
elsif ($bytes > 1000){
   $bytes = ( sprintf( "%0.2f", $bytes/1000 )). " Kb/s"; 
}
else{ 
   $bytes = sprintf( "%0.2f", $bytes ). "b/s";
}                                                                  

Thank you for your help!

like image 498
Mad_Ady Avatar asked Sep 30 '08 13:09

Mad_Ady


4 Answers

The Number::Bytes::Human module should be able to help you out.

An example of how to use it can be found in its synopsis:

  use Number::Bytes::Human qw(format_bytes);

  $size = format_bytes(0); # '0'
  $size = format_bytes(2*1024); # '2.0K'

  $size = format_bytes(1_234_890, bs => 1000); # '1.3M'
  $size = format_bytes(1E9, bs => 1000); # '1.0G'

  # the OO way
  $human = Number::Bytes::Human->new(bs => 1000, si => 1);
  $size = $human->format(1E7); # '10MB'
  $human->set_options(zero => '-');
  $size = $human->format(0); # '-'
like image 138
WalkingRandomly Avatar answered Nov 10 '22 02:11

WalkingRandomly


Number::Bytes::Human seems to do exactly what you want.

like image 33
Swaroop C H Avatar answered Nov 10 '22 02:11

Swaroop C H


sub magnitudeformat {
  my $val = shift;
  my $expstr;

  my $exp = log($val) / log(10);
     if ($exp < 3)  { return $val;   }
  elsif ($exp < 6)  { $exp = 3;  $expstr = "K"; }
  elsif ($exp < 9)  { $exp = 6;  $expstr = "M"; }
  elsif ($exp < 12) { $exp = 9;  $expstr = "G"; } # Or "B".
  else              { $exp = 12; $expstr = "T"; }

  return sprintf("%0.1f%s", $val/(10**$exp), $expstr);
}
like image 2
Michael Cramer Avatar answered Nov 10 '22 04:11

Michael Cramer


In pure Perl form, I've done this with a nested ternary operator to cut on verbosity:

sub BytesToReadableString($) {
   my $c = shift;
   $c >= 1073741824 ? sprintf("%0.2fGB", $c/1073741824)
      : $c >= 1048576 ? sprintf("%0.2fMB", $c/1048576)
      : $c >= 1024 ? sprintf("%0.2fKB", $c/1024)
      : $c . "bytes";
}

print BytesToReadableString(225939) . "/s\n";

Outputs:

220.64KB/s
like image 2
spoulson Avatar answered Nov 10 '22 03:11

spoulson