Como posso converter um número em sua forma múltipla em Perl?
Pergunta
Você sabe um método / sub / módulo fácil e direta que me permite converter um número (digamos 1.234.567,89) para uma forma facilmente legível? - algo como 1.23M
Agora eu posso fazer isso através de várias comparações, mas eu não estou feliz com o meu método:
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";
}
Obrigado por sua ajuda!
Solução
O Número :: módulo Bytes :: Humano deve ser capaz de ajuda -lo.
Um exemplo de como usá-lo pode ser encontrada em sua sinopse:
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); # '-'
Outras dicas
Número :: Bytes :: Humano parece fazer exatamente o que você quer.
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);
}
Em forma de Perl puro, eu fiz isso com um operador ternário aninhada para corte na verbosidade:
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";
Saídas:
220.64KB/s
Este trecho é em PHP, e é vagamente baseado em alguns exemplos alguém teve em seu site em algum lugar (amigo desculpe, não me lembro).
O conceito básico é em vez de usar se, use um loop.
function formatNumberThousands($a,$dig)
{
$unim = array("","k","m","g");
$c = 0;
while ($a>=1000 && $c<=3) {
$c++;
$a = $a/1000;
}
$d = $dig-ceil(log10($a));
return number_format($a,($c ? $d : 0))."".$unim[$c];
}
A chamada number_format () é uma função de biblioteca PHP que retorna um string com vírgulas entre os grupos de milhares. Eu não tenho certeza se algo como ela existe em perl.
O parâmetro $ escavação estabelece um limite para o número de dígitos para mostrar. Se $ escavação é 2, ele vai te dar 1.2K de 1237.
Para bytes formato, basta dividir por 1024 em vez disso.
Esta função está em uso em algum código de produção para este dia.