public static function formatNumber($value, $digits_left = 3, $digits_right = 0, $only_down = false, $noTrailingZero = true)
{
if ($value == 0) {
return '0';
}
$originalValue = $value;
//number_format is not multibyte safe, str_replace is safe
if ($digits_left === 0) {
$value = number_format($value, $digits_right, __('.'), __(','));
if ($originalValue != 0 && floatval($value) == 0) {
$value = ' <' . 1 / pow(10, $digits_right);
}
return $value;
}
// this units needs no translation, ISO
$units = array(-8 => 'y', -7 => 'z', -6 => 'a', -5 => 'f', -4 => 'p', -3 => 'n', -2 => 'µ', -1 => 'm', 0 => ' ', 1 => 'k', 2 => 'M', 3 => 'G', 4 => 'T', 5 => 'P', 6 => 'E', 7 => 'Z', 8 => 'Y');
// check for negative value to retain sign
if ($value < 0) {
$sign = '-';
$value = abs($value);
} else {
$sign = '';
}
$dh = pow(10, $digits_right);
/*
* This gives us the right SI prefix already,
* but $digits_left parameter not incorporated
*/
$d = floor(log10($value) / 3);
/*
* Lowering the SI prefix by 1 gives us an additional 3 zeros
* So if we have 3,6,9,12.. free digits ($digits_left - $cur_digits)
* to use, then lower the SI prefix
*/
$cur_digits = floor(log10($value / pow(1000, $d)) + 1);
if ($digits_left > $cur_digits) {
$d -= floor(($digits_left - $cur_digits) / 3);
}
if ($d < 0 && $only_down) {
$d = 0;
}
$value = round($value / (pow(1000, $d) / $dh)) / $dh;
$unit = $units[$d];
// number_format is not multibyte safe, str_replace is safe
$formattedValue = number_format($value, $digits_right, __('.'), __(','));
// If we don't want any zeros, remove them now
if ($noTrailingZero && strpos($formattedValue, '.') !== false) {
$formattedValue = preg_replace('/\\.?0+$/', '', $formattedValue);
}
if ($originalValue != 0 && floatval($value) == 0) {
return ' <' . number_format(1 / pow(10, $digits_right), $digits_right, __('.'), __(',')) . ' ' . $unit;
}
return $sign . $formattedValue . ' ' . $unit;
}