Formatting bytes with significant figures in PHP

Posted on 18 Dec 2008

Hopefully these PHP snippets can be useful to someone. The first function formats a number to a specified number of significant figures (this is different from rounding to a number of decimal places). The second function uses the first to display a number of bytes with appropriate human-friendly formatting. e.g. 12345B becomes 123kB (to three significant figures).

/** Calculate $value to $sigFigs significant figures */
function sigFig($value, $sigFigs = 3) {
    //convert to scientific notation e.g. 12345 -> 1.2345x10^4
    //where $significand is 1.2345 and $exponent is 4
    $exponent = floor(log10(abs($value))+1);
    $significand = round(($value
        / pow(10, $exponent))
        * pow(10, $sigFigs))
        / pow(10, $sigFigs);
    return $significand * pow(10, $exponent);
}

/** Format $value with the appropriate SI prefix symbol */
function formatBytes($value, $sigFigs = 3)
{
    //SI prefix symbols
    $units = array('', 'k', 'M', 'G', 'T', 'P', 'E');
    //how many powers of 1000 in the value?
    $index = floor(log10($value)/3);
    $value = $index ? $value/pow(1000, $index) : $value;
    return sigFig($value, $sigFigs) . $units[$index] . 'B';
}

//Example output
echo formatBytes(12345, 1); //10kB
echo formatBytes(9876543210); //9.88GB

Consider this code public domain - you can do whatever you like with it.