2008-09-30 7 views
7

¿Conoces un método/sub/módulo fácil y directo que me permite convertir un número (digamos 1234567.89) en una forma fácil de leer, algo así como 1.23M?¿Cómo puedo convertir un número a su forma múltiple en Perl?

En este momento me puede hacer esto al hacer varias comparaciones, pero no estoy feliz con mi 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"; 
}                 

Gracias por su ayuda!

Respuesta

20

El módulo Number::Bytes::Human debería ser capaz de ayudarlo.

Un ejemplo de cómo utilizarlo se puede encontrar en su sinopsis:

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); # '-' 
2

En forma Perl puro, he hecho esto con un operador ternario anidada para cortar el nivel de detalle:

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"; 

Salidas:

220.64KB/s
+2

¿Qué pasa con el escalar superfluo ($ c)? – dland

+0

La función escalar es una typecasts. Es una forma fácil de convertir un entero en una cadena. También elimina la ambigüedad entre el texto y las operaciones numéricas. – spoulson

+0

Perl no se encasilla en absoluto. Cualquier operación de cadena, como el operador de concatenación, la convertirá en una cadena para usted. –

0

Este fragmento está en PHP, y se basa vagamente en algún ejemplo alguien más tenía en su sitio web en alguna parte (lo siento amigo, no recuerdo).

El concepto básico es en lugar de usar if, usar un bucle.

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]; 
} 

La llamada num_formato() es una función de biblioteca PHP que devuelve una cadena con comas entre los grupos de miles. No estoy seguro de si algo así existe en Perl.

El parámetro $ dig establece un límite en la cantidad de dígitos para mostrar. Si $ dig es 2, obtendrá 1.2k de 1237.

Para formatear bytes, solo divida por 1024.

Esta función está en uso en algún código de producción hasta el día de hoy.

+0

El cartel preguntó por Perl, no por PHP. El código PHP no lo ayudará. – Mei

2
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); 
} 
+2

¿Por qué parar en T? P, E, Z, Y, X, W, V, U, TD, S, R, Q, PP, O, N, MI y L siguen (aunque solo a través de Y son "oficiales"). – ysth

Cuestiones relacionadas