Formatting bytes with significant figures in PHP
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.
May 5th, 2009 at 22:38
Just a note… to make your sigFig function work with negative numbers you should change the $exponent variable to:
$exponent = floor(log10(abs($value))+1);
Other then that a nice solution to this problem, thanks!
May 5th, 2009 at 23:07
Good call. Updated. Thanks!
June 1st, 2009 at 12:54
Cheers dude, just saved me some time.
September 13th, 2009 at 19:09
Thanks a lot, Tamlyn, for sharing your terrific significant figures function. It’s really an omission from PHP and should be a native PHP function. You’ve saved people like me a lot of time and brain cycles from having to try to reinvent your wheel here!
October 24th, 2009 at 21:29
Hi Tamlyn
One more comment based on using your excellent function. It returns a “division-by-zero” error when $value == 0 (because log (0) is mathematically undefined). To avoid the error at this mathematical discontinuity, I simply inserted this line of code at the beginning of the function:
if ($value == 0) return 0;
Thanks again for a tremendous contribution to the PHP community!
Paul
November 26th, 2009 at 16:02
I just used your function to format network tx/rx rates in a PHP script running on my Zaurus sl-5500. It writes that and other server info to /dev/ttyS0, where my microcontroller listens and interfaces with a 16×2 character LCD screen.
THANK YOU! You could imagine attempting this gives me plenty of headaches already! Wonderful code.