Formatieren Sie Bytes in Kilobyte, Megabyte, Gigabyte

184

Szenario: Die Größe verschiedener Dateien wird als Byte in einer Datenbank gespeichert. Wie können diese Größeninformationen am besten in Kilobyte, Megabyte und Gigabyte formatiert werden? Zum Beispiel habe ich eine MP3, die Ubuntu als "5,2 MB (5445632 Bytes)" anzeigt. Wie würde ich dies auf einer Webseite als "5,2 MB" anzeigen UND Dateien mit weniger als einem Megabyte als KB und Dateien mit einem Gigabyte und mehr als GB anzeigen lassen?

Leepowers
quelle
3
Ich glaube, Sie sollten eine Funktion erstellen, die dies tut. Teilen Sie einfach die Zahl durch 1024 und sehen Sie sich das Ergebnis an. Wenn es mehr als 1024 ist, dann wieder teilen.
Ivan Nevostruev

Antworten:

319
function formatBytes($bytes, $precision = 2) { 
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 

    $bytes = max($bytes, 0); 
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
    $pow = min($pow, count($units) - 1); 

    // Uncomment one of the following alternatives
    // $bytes /= pow(1024, $pow);
    // $bytes /= (1 << (10 * $pow)); 

    return round($bytes, $precision) . ' ' . $units[$pow]; 
} 

(Aus php.net entnommen , gibt es dort viele andere Beispiele, aber dieses gefällt mir am besten :-)

Löwe
quelle
8
Wenn Sie $bytes /= (1 << (10 * $pow))oder dergleichen verwendet haben, könnte ich es besser mögen. :-P
Chris Jester-Young
5
Los geht's: D (Ich persönlich mag keine bitweise Arithmetik, weil es schwer zu verstehen ist, wenn Sie nicht daran gewöhnt sind ...)
Leo
3
@ Justin das ist, weil 9287695/1024/1024 in der Tat 8.857 ist :)
Mahn
30
Eigentlich ist es KiB, MiB, GiBund TiBda Sie Division durch 1024. Wenn Sie durch 1000es geteilt würden, wäre ohne die i.
Devator
7
Uncomment one of the following alternativeswar etwas, das ich 5 Minuten lang nicht bemerkt habe ...
Arnis Juraga
210

Dies ist die sauberste Implementierung von Chris Jester-Young, die ich je gesehen habe, kombiniert mit der von php.net und einem präzisen Argument.

function formatBytes($size, $precision = 2)
{
    $base = log($size, 1024);
    $suffixes = array('', 'K', 'M', 'G', 'T');   

    return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
}

echo formatBytes(24962496);
// 23.81M

echo formatBytes(24962496, 0);
// 24M

echo formatBytes(24962496, 4);
// 23.8061M
John Himmelman
quelle
8
es hat 2 Fehler - addiere 1 zu (mindestens kleiner) Dateigröße - funktioniert nicht mit 0 (return NAN)
maazza
Schön. Gibt es eine Version davon umgekehrt?
Luke
3
Ein kleiner Traum : $suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); Ich möchte eine Yottabyte-Festplatte! :-P
SpYk3HH
1
Ich musste die $ -Größe auf das Doppelte umwandeln, damit es funktioniert. Hier ist, was für mich funktioniert hat: Funktion formatBytes ($ Größe, $ Genauigkeit = 2) {$ base = log (floatval ($ Größe)) / log (1024); $ Suffixe = Array ('', 'k', 'M', 'G', 'T'); Rückkehrrunde (pow (1024, $ base - floor ($ base)), $ präzise). $ Suffixe [Etage ($ Basis)]; }}
Christopher Gray
formatBytes(259748192, 3)kehrt zurück, 259748192 MBwas nicht richtig ist
Flip
97

Pseudocode:

$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
Chris Jester-Young
quelle
Microsoft und Apple verwenden 1024, dies hängt von Ihrem Anwendungsfall ab.
Parsa Yazdani
15

Dies ist Kohanas Implementierung, Sie könnten sie verwenden:

public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE)
{
    // Format string
    $format = ($format === NULL) ? '%01.2f %s' : (string) $format;

    // IEC prefixes (binary)
    if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE)
    {
        $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
        $mod   = 1024;
    }
    // SI prefixes (decimal)
    else
    {
        $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
        $mod   = 1000;
    }

    // Determine unit to use
    if (($power = array_search((string) $force_unit, $units)) === FALSE)
    {
        $power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0;
    }

    return sprintf($format, $bytes / pow($mod, $power), $units[$power]);
}
Ryeguy
quelle
Ihre Idee, eine Option zwischen 1024 und 1000 Leistung zu haben, ist gut. Aber diese Implementierung ist wirklich komisch. $force_unitund $sischeinen das gleiche zu tun. Sie können auch eine beliebige Zeichenfolge mit einem "i" an übergeben $force_unit, da diese auf Position getestet wird. Die Dezimalformatierung ist ebenfalls übertrieben.
Gus Neves
14

Teilen Sie es einfach durch 1024 für kb, 1024 ^ 2 für mb und 1024 ^ 3 für GB. So einfach ist das.

Vonder
quelle
8

Nur meine Alternative, kurz und sauber:

/**
 * @param int $bytes Number of bytes (eg. 25907)
 * @param int $precision [optional] Number of digits after the decimal point (eg. 1)
 * @return string Value converted with unit (eg. 25.3KB)
 */
function formatBytes($bytes, $precision = 2) {
    $unit = ["B", "KB", "MB", "GB"];
    $exp = floor(log($bytes, 1024)) | 0;
    return round($bytes / (pow(1024, $exp)), $precision).$unit[$exp];
}

oder dümmer und effizienter:

function formatBytes($bytes, $precision = 2) {
    if ($bytes > pow(1024,3)) return round($bytes / pow(1024,3), $precision)."GB";
    else if ($bytes > pow(1024,2)) return round($bytes / pow(1024,2), $precision)."MB";
    else if ($bytes > 1024) return round($bytes / 1024, $precision)."KB";
    else return ($bytes)."B";
}
Guari
quelle
7

Verwenden Sie diese Funktion, wenn Sie einen Funktionscode wünschen

bcdiv ()

$size = 11485760;
echo bcdiv($size, 1048576, 0); // return: 10

echo bcdiv($size, 1048576, 2); // return: 10,9

echo bcdiv($size, 1048576, 2); // return: 10,95

echo bcdiv($size, 1048576, 3); // return: 10,953
Yanni
quelle
6

Ich weiß, dass es vielleicht etwas spät ist, diese Frage zu beantworten, aber mehr Daten werden niemanden umbringen. Hier ist eine sehr schnelle Funktion:

function format_filesize($B, $D=2){
    $S = 'BkMGTPEZY';
    $F = floor((strlen($B) - 1) / 3);
    return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F].'B';
}

BEARBEITEN: Ich habe meinen Beitrag aktualisiert, um den von camomileCase vorgeschlagenen Fix aufzunehmen:

function format_filesize($B, $D=2){
    $S = 'kMGTPEZY';
    $F = floor((strlen($B) - 1) / 3);
    return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F-1].'B';
}
David Bélanger
quelle
1
Sie erhalten ein doppeltes B (BB) für kleine Werte von $ B, da Sie als Workaround "$ S = 'kMGTPEZY'" erstellen und anstelle von "@ $ S [$ F]" "@ $ S [$" ausführen können F-1].
CamomileCase
@camomileCase Zweieinhalb Jahre später - Ich habe meine Antwort aktualisiert. Vielen Dank.
David Bélanger
4

Einfache Funktion

function formatBytes($size, $precision = 0){
    $unit = ['Byte','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];

    for($i = 0; $size >= 1024 && $i < count($unit)-1; $i++){
        $size /= 1024;
    }

    return round($size, $precision).' '.$unit[$i];
}

echo formatBytes('1876144', 2);
//returns 1.79 MiB
SebHallin
quelle
3

Flexible Lösung:

function size($size, array $options=null) {

    $o = [
        'binary' => false,
        'decimalPlaces' => 2,
        'decimalSeparator' => '.',
        'thausandsSeparator' => '',
        'maxThreshold' => false, // or thresholds key
        'sufix' => [
            'thresholds' => ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
            'decimal' => ' {threshold}B',
            'binary' => ' {threshold}iB',
            'bytes' => ' B'
        ]
    ];

    if ($options !== null)
        $o = array_replace_recursive($o, $options);

    $base = $o['binary'] ? 1024 : 1000;
    $exp = $size ? floor(log($size) / log($base)) : 0;

    if (($o['maxThreshold'] !== false) &&
        ($o['maxThreshold'] < $exp)
    )
        $exp = $o['maxThreshold'];

    return !$exp
        ? (round($size) . $o['sufix']['bytes'])
        : (
            number_format(
                $size / pow($base, $exp),
                $o['decimalPlaces'],
                $o['decimalSeparator'],
                $o['thausandsSeparator']
            ) .
            str_replace(
                '{threshold}',
                $o['sufix']['thresholds'][$exp],
                $o['sufix'][$o['binary'] ? 'binary' : 'decimal']
            )
        );
}

var_dump(size(disk_free_space('/')));
// string(8) "14.63 GB"
var_dump(size(disk_free_space('/'), ['binary' => true]));
// string(9) "13.63 GiB"
var_dump(size(disk_free_space('/'), ['maxThreshold' => 2]));
// string(11) "14631.90 MB"
var_dump(size(disk_free_space('/'), ['binary' => true, 'maxThreshold' => 2]));
// string(12) "13954.07 MiB"
Pavel Tzonkov
quelle
2

Es gelang mir mit folgender Funktion:

    function format_size($size) {
        $mod = 1024;
        $units = explode(' ','B KB MB GB TB PB');
        for ($i = 0; $size > $mod; $i++) {
            $size /= $mod;
        }
        return round($size, 2) . ' ' . $units[$i];
    }
Janith Chinthana
quelle
2
Achtung: K steht für Kelvin und k steht für Kilo.
ZeWaren
2

Mein Ansatz

    function file_format_size($bytes, $decimals = 2) {
  $unit_list = array('B', 'KB', 'MB', 'GB', 'PB');

  if ($bytes == 0) {
    return $bytes . ' ' . $unit_list[0];
  }

  $unit_count = count($unit_list);
  for ($i = $unit_count - 1; $i >= 0; $i--) {
    $power = $i * 10;
    if (($bytes >> $power) >= 1)
      return round($bytes / (1 << $power), $decimals) . ' ' . $unit_list[$i];
  }
}
user24087
quelle
2

Ich weiß nicht, warum Sie es so kompliziert machen sollten wie die anderen.

Der folgende Code ist viel einfacher zu verstehen und etwa 25% schneller als die anderen Lösungen, die die Protokollfunktion verwenden (20 Mio.-mal als Funktion mit unterschiedlichen Parametern bezeichnet).

function formatBytes($bytes, $precision = 2) {
    $units = ['Byte', 'Kilobyte', 'Megabyte', 'Gigabyte', 'Terabyte'];
    $i = 0;

    while($bytes > 1024) {
        $bytes /= 1024;
        $i++;
    }
    return round($bytes, $precision) . ' ' . $units[$i];
}
ZettiCaletti
quelle
2

Ich habe dies getan, indem ich alle Eingaben in Bytes konvertiert und so in alle benötigten Ausgaben konvertiert habe. Außerdem habe ich eine Zusatzfunktion verwendet, um die Basis 1000 oder 1024 zu erhalten, aber es blieb flexibel, 1024 für den gängigen Typ zu verwenden (ohne 'i', wie MB anstelle von MiB).

    public function converte_binario($size=0,$format_in='B',$format_out='MB',$force_in_1024=false,$force_out_1024=false,$precisao=5,$return_format=true,$decimal=',',$centena=''){
    $out = false;

    if( (is_numeric($size)) && ($size>0)){
        $in_data = $this->converte_binario_aux($format_in,$force_in_1024);
        $out_data = $this->converte_binario_aux($format_out,$force_out_1024);

        // se formato de entrada e saída foram encontrados
        if( ((isset($in_data['sucesso'])) && ($in_data['sucesso']==true)) && ((isset($out_data['sucesso'])) && ($out_data['sucesso']==true))){
            // converte formato de entrada para bytes.
            $size_bytes_in = $size * (pow($in_data['base'], $in_data['pot']));
            $size_byte_out = (pow($out_data['base'], $out_data['pot']));
            // transforma bytes na unidade de destino
            $out = number_format($size_bytes_in / $size_byte_out,$precisao,$decimal,$centena);
            if($return_format){
                $out .= $format_out;
            }
        }
    }
    return $out;
}

public function converte_binario_aux($format=false,$force_1024=false){
    $out = [];
    $out['sucesso'] = false;
    $out['base'] = 0;
    $out['pot'] = 0;
    if((is_string($format) && (strlen($format)>0))){
        $format = trim(strtolower($format));
        $units_1000 = ['b','kb' ,'mb' ,'gb' ,'tb' ,'pb' ,'eb' ,'zb' ,'yb' ];
        $units_1024 = ['b','kib','mib','gib','tib','pib','eib','zib','yib'];
        $pot = array_search($format,$units_1000);
        if( (is_numeric($pot)) && ($pot>=0)){
            $out['pot'] = $pot;
            $out['base'] = 1000;
            $out['sucesso'] = true;
        }
        else{
            $pot = array_search($format,$units_1024);
            if( (is_numeric($pot)) && ($pot>=0)){
                $out['pot'] = $pot;
                $out['base'] = 1024;
                $out['sucesso'] = true;
            }
        }
        if($force_1024){
            $out['base'] = 1024;
        }
    }
    return $out;
}
Gabriel Barcellos
quelle
1

Versuche dies ;)

function bytesToSize($bytes) {
                $sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
                if ($bytes == 0) return 'n/a';
                $i = intval(floor(log($bytes) / log(1024)));
                if ($i == 0) return $bytes . ' ' . $sizes[$i]; 
                return round(($bytes / pow(1024, $i)),1,PHP_ROUND_HALF_UP). ' ' . $sizes[$i];
            }
echo bytesToSize(10000050300);
Yahia Mgarrech
quelle
1
function changeType($size, $type, $end){
    $arr = ['B', 'KB', 'MB', 'GB', 'TB'];
    $tSayi = array_search($type, $arr);
    $eSayi = array_search($end, $arr);
    $pow = $eSayi - $tSayi;
    return $size * pow(1024 * $pow) . ' ' . $end;
}

echo changeType(500, 'B', 'KB');
Kerem Çakır
quelle
1
function convertToReadableSize($size)
{
  $base = log($size) / log(1024);
  $suffix = array("B", "KB", "MB", "GB", "TB");
  $f_base = floor($base);
  return round(pow(1024, $base - floor($base)), 1) . $suffix[$f_base];
}

Rufen Sie einfach die Funktion auf

echo convertToReadableSize(1024); // Outputs '1KB'
echo convertToReadableSize(1024 * 1024); // Outputs '1MB'
Madushanka Sampath
quelle
1

Dies funktioniert mit dem letzten PHP

function formatBytes($bytes, $precision = 2) { 
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 

    $bytes = max($bytes, 0); 
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
    $pow = min($pow, count($units) - 1); 

    $bytes /= pow(1024, $pow); 

    return round($bytes, $precision) . ' ' . $units[$pow]; 
} 
Josué Leo Moreno
quelle
Alles, was dort getan wurde, ist das gleiche exakte Kopieren eines Beispiels aus PHP.net, das der Hauptbeantworter 2010 erst 8 Jahre später durchgeführt hat.
JakeGould
1

Obwohl etwas abgestanden, bietet diese Bibliothek eine getestete und robuste Konvertierungs-API:

https://github.com/gabrielelana/byte-units

Einmal installiert:

\ByteUnits\Binary::bytes(1024)->format();

// Output: "1.00KiB"

Und in die andere Richtung zu konvertieren:

\ByteUnits\Binary::parse('1KiB')->numberOfBytes();

// Output: "1024"

Über die grundlegende Konvertierung hinaus bietet es Methoden zum Addieren, Subtrahieren, Vergleichen usw.

Ich bin in keiner Weise mit dieser Bibliothek verbunden.

Ben Johnson
quelle
0
function byte_format($size) {
    $bytes = array( ' KB', ' MB', ' GB', ' TB' );
    foreach ($bytes as $val) {
        if (1024 <= $size) {
            $size = $size / 1024;
            continue;
        }
        break;
    }
    return round( $size, 1 ) . $val;
}
mooky
quelle
0

Hier ist eine vereinfachte Implementierung der Funktion Drupal format_size :

/**
 * Generates a string representation for the given byte count.
 *
 * @param $size
 *   A size in bytes.
 *
 * @return
 *   A string representation of the size.
 */
function format_size($size) {
  if ($size < 1024) {
    return $size . ' B';
  }
  else {
    $size = $size / 1024;
    $units = ['KB', 'MB', 'GB', 'TB'];
    foreach ($units as $unit) {
      if (round($size, 2) >= 1024) {
        $size = $size / 1024;
      }
      else {
        break;
      }
    }
    return round($size, 2) . ' ' . $unit;
  }
}
ya.teck
quelle
0

Es ist etwas spät, aber eine etwas schnellere Version der akzeptierten Antwort finden Sie unten:

function formatBytes($bytes, $precision)
{
    $unit_list = array
    (
        'B',
        'KB',
        'MB',
        'GB',
        'TB',
    );

    $bytes = max($bytes, 0);
    $index = floor(log($bytes, 2) / 10);
    $index = min($index, count($unit_list) - 1);
    $bytes /= pow(1024, $index);

    return round($bytes, $precision) . ' ' . $unit_list[$index];
}

Es ist effizienter, da anstelle von zwei Log-E-Vorgängen nur ein Log-2-Vorgang ausgeführt wird.

Es ist jedoch tatsächlich schneller, die offensichtlichere Lösung unten zu finden:

function formatBytes($bytes, $precision)
{
    $unit_list = array
    (
        'B',
        'KB',
        'MB',
        'GB',
        'TB',
    );

    $index_max = count($unit_list) - 1;
    $bytes = max($bytes, 0);

    for ($index = 0; $bytes >= 1024 && $index < $index_max; $index++)
    {
        $bytes /= 1024;
    }

    return round($bytes, $precision) . ' ' . $unit_list[$index];
}

Dies liegt daran, dass der Index gleichzeitig mit dem Wert der Anzahl der Bytes in der entsprechenden Einheit berechnet wird. Dies verkürzte die Ausführungszeit um etwa 35% (eine Geschwindigkeitssteigerung von 55%).

user3690595
quelle
0

Eine weitere komprimierte Implementierung, die in die Basis 1024 (binär) oder die Basis 1000 (dezimal) übersetzt werden kann und daher auch mit unglaublich großen Zahlen funktioniert, daher die Verwendung der bc-Bibliothek:

function renderSize($byte,$precision=2,$mibi=true)
{
    $base = (string)($mibi?1024:1000);
    $labels = array('K','M','G','T','P','E','Z','Y');
    for($i=8;$i>=1;$i--)
        if(bccomp($byte,bcpow($base, $i))>=0)
            return bcdiv($byte,bcpow($base, $i), $precision).' '.$labels[$i-1].($mibi?'iB':'B');
    return $byte.' Byte';
}
Christian
quelle
Nur eine kleine Randnotiz; bcpow()Typeerror - Ausnahme , wenn werfen wird $baseund $ikeine String - Werte. Getestet auf PHP Version 7.0.11.
David Cery
Vielen Dank! Ich habe den String Caster hinzugefügt und einen Offset-Fehler behoben :)
Christian
0

Ich dachte, ich würde eine Vernetzung von zwei Übermittler-Codes hinzufügen (mit John Himmelmans Code, der sich in diesem Thread befindet, und mit Eugene Kuzmenkos Code), den ich verwende.

function swissConverter($value, $format = true, $precision = 2) {
    //Below converts value into bytes depending on input (specify mb, for 
    //example)
    $bytes = preg_replace_callback('/^\s*(\d+)\s*(?:([kmgt]?)b?)?\s*$/i', 
    function ($m) {
        switch (strtolower($m[2])) {
          case 't': $m[1] *= 1024;
          case 'g': $m[1] *= 1024;
          case 'm': $m[1] *= 1024;
          case 'k': $m[1] *= 1024;
        }
        return $m[1];
        }, $value);
    if(is_numeric($bytes)) {
        if($format === true) {
            //Below converts bytes into proper formatting (human readable 
            //basically)
            $base = log($bytes, 1024);
            $suffixes = array('', 'KB', 'MB', 'GB', 'TB');   

            return round(pow(1024, $base - floor($base)), $precision) .' '. 
                     $suffixes[floor($base)];
        } else {
            return $bytes;
        }
    } else {
        return NULL; //Change to prefered response
    }
}

Dies verwendet Eugenes Code, um die $valuein Bytes zu formatieren (ich behalte meine Daten in MB, also konvertiert es meine Daten: 10485760 MBin 10995116277760) - es verwendet dann Johns Code, um sie in den richtigen Anzeigewert ( 10995116277760in 10 TB) zu konvertieren .

Ich fand das sehr hilfreich - also meinen Dank an die beiden Einsender!

EML
quelle
0

Extrem einfache Funktion zum Abrufen der Größe menschlicher Dateien.

Ursprüngliche Quelle: http://php.net/manual/de/function.filesize.php#106569

Code kopieren / einfügen:

<?php
function human_filesize($bytes, $decimals = 2) {
  $sz = 'BKMGTP';
  $factor = floor((strlen($bytes) - 1) / 3);
  return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
?>
John Erck
quelle
0

Ich habe meine eigene Funktion entwickelt, die die vom Menschen lesbare Speichergröße in verschiedene Größen umwandelt.

function convertMemorySize($strval, string $to_unit = 'b')
{
    $strval    = strtolower(str_replace(' ', '', $strval));
    $val       = floatval($strval);
    $to_unit   = strtolower(trim($to_unit))[0];
    $from_unit = str_replace($val, '', $strval);
    $from_unit = empty($from_unit) ? 'b' : trim($from_unit)[0];
    $units     = 'kmgtph';  // (k)ilobyte, (m)egabyte, (g)igabyte and so on...


    // Convert to bytes
    if ($from_unit !== 'b')
        $val *= 1024 ** (strpos($units, $from_unit) + 1);


    // Convert to unit
    if ($to_unit !== 'b')
        $val /= 1024 ** (strpos($units, $to_unit) + 1);


    return $val;
}


convertMemorySize('1024Kb', 'Mb');  // 1
convertMemorySize('1024', 'k')      // 1
convertMemorySize('5.2Mb', 'b')     // 5452595.2
convertMemorySize('10 kilobytes', 'bytes') // 10240
convertMemorySize(2048, 'k')        // By default convert from bytes, result is 2

Diese Funktion akzeptiert alle Abkürzungen für die Speichergröße wie "Megabyte, MB, MB, MB, MB, Kilobyte, K, KB, B, Terabyte, T ..." und ist daher Tippfehler.

Juan Lago
quelle
0

Basierend auf Leos Antwort , füge hinzu

  • Unterstützung für negative
  • Unterstützung 0 <Wert <1 (Beispiel: 0,2, verursacht log (Wert) = negative Zahl)

Wenn Sie die maximale Einheit auf Mega setzen möchten, wechseln Sie zu $units = explode(' ', ' K M');


function formatUnit($value, $precision = 2) {
    $units = explode(' ', ' K M G T P E Z Y');

    if ($value < 0) {
        return '-' . formatUnit(abs($value));
    }

    if ($value < 1) {
        return $value . $units[0];
    }

    $power = min(
        floor(log($value, 1024)),
        count($units) - 1
    );

    return round($value / pow(1024, $power), $precision) . $units[$power];
}
Steely Wing
quelle