/** * Formats $value to the given length and appends SI prefixes * with a $length of 0 no truncation occurs, number is only formated * to the current locale * * examples: * <code> * echo PMA_formatNumber(123456789, 6); // 123,457 k * echo PMA_formatNumber(-123456789, 4, 2); // -123.46 M * echo PMA_formatNumber(-0.003, 6); // -3 m * echo PMA_formatNumber(0.003, 3, 3); // 0.003 * echo PMA_formatNumber(0.00003, 3, 2); // 0.03 m * echo PMA_formatNumber(0, 6); // 0 * </code> * * @param double $value the value to format * @param integer $digits_left number of digits left of the comma * @param integer $digits_right number of digits right of the comma * @param boolean $only_down do not reformat numbers below 1 * @param boolean $noTrailingZero removes trailing zeros right of the comma * (default: true) * * @return string the formatted value and its unit * * @access public */ function PMA_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 / PMA_pow(10, $digits_right); } return PMA_localizeNumber($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 = PMA_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 / PMA_pow(1000, $d, 'pow')) + 1); if ($digits_left > $cur_digits) { $d -= floor(($digits_left - $cur_digits) / 3); } if ($d < 0 && $only_down) { $d = 0; } $value = round($value / (PMA_pow(1000, $d, 'pow') / $dh)) / $dh; $unit = $units[$d]; // If we dont want any zeros after the comma just add the thousand seperator if ($noTrailingZero) { $value = PMA_localizeNumber(preg_replace('/(?<=\\d)(?=(\\d{3})+(?!\\d))/', ',', $value)); } else { //number_format is not multibyte safe, str_replace is safe $value = PMA_localizeNumber(number_format($value, $digits_right)); } if ($originalValue != 0 && floatval($value) == 0) { return ' <' . 1 / PMA_pow(10, $digits_right) . ' ' . $unit; } return $sign . $value . ' ' . $unit; }
/** * Formats $value to the given length and appends SI prefixes * $comma is not substracted from the length * with a $length of 0 no truncation occurs, number is only formated * to the current locale * * examples: * <code> * echo PMA_formatNumber(123456789, 6); // 123,457 k * echo PMA_formatNumber(-123456789, 4, 2); // -123.46 M * echo PMA_formatNumber(-0.003, 6); // -3 m * echo PMA_formatNumber(0.003, 3, 3); // 0.003 * echo PMA_formatNumber(0.00003, 3, 2); // 0.03 m * echo PMA_formatNumber(0, 6); // 0 * * </code> * @param double $value the value to format * @param integer $length the max length * @param integer $comma the number of decimals to retain * @param boolean $only_down do not reformat numbers below 1 * * @return string the formatted value and its unit * * @access public * * @version 1.1.0 - 2005-10-27 */ function PMA_formatNumber($value, $length = 3, $comma = 0, $only_down = false) { //number_format is not multibyte safe, str_replace is safe if ($length === 0) { return PMA_localizeNumber(number_format($value, $comma)); } // 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'); // we need at least 3 digits to be displayed if (3 > $length + $comma) { $length = 3 - $comma; } // check for negative value to retain sign if ($value < 0) { $sign = '-'; $value = abs($value); } else { $sign = ''; } $dh = PMA_pow(10, $comma); $li = PMA_pow(10, $length); $unit = $units[0]; if ($value >= 1) { for ($d = 8; $d >= 0; $d--) { if (isset($units[$d]) && $value >= $li * PMA_pow(1000, $d - 1)) { $value = round($value / (PMA_pow(1000, $d) / $dh)) / $dh; $unit = $units[$d]; break 1; } // end if } // end for } elseif (!$only_down && (double) $value !== 0.0) { for ($d = -8; $d <= 8; $d++) { // force using pow() because of the negative exponent if (isset($units[$d]) && $value <= $li * PMA_pow(1000, $d - 1, 'pow')) { $value = round($value / (PMA_pow(1000, $d, 'pow') / $dh)) / $dh; $unit = $units[$d]; break 1; } // end if } // end for } // end if ($value >= 1) elseif (!$only_down && (float) $value !== 0.0) //number_format is not multibyte safe, str_replace is safe $value = PMA_localizeNumber(number_format($value, $comma)); return $sign . $value . ' ' . $unit; }