Форматировать число до N значащих цифр в PHP
Я хотел бы отформатировать (округлить) числа с плавающей запятой (двойные), чтобы сказать, например, 2 значащие цифры, например, так:
1 => 1
11 => 11
111 => 110
119 => 120
0.11 => 0.11
0.00011 => 0.00011
0.000111 => 0.00011
Таким образом, произвольная точность остается неизменной
Я ожидаю, что есть какая-то хорошая функция для него уже встроена, но пока не смог найти ни одной
Мне указали на Как округлить до ближайшего значащего числа в php, которое близко, но не работает для N значащих цифр, и я не уверен, что он делает с числами 0.000XXX
3 ответа
Чтобы получить число, округленное до n значащих цифр, вам нужно найти размер числа в степенях десять и вычесть его из n.
Это прекрасно работает для простого округления:
function sigFig($value, $digits)
{
if ($value == 0) {
$decimalPlaces = $digits - 1;
} elseif ($value < 0) {
$decimalPlaces = $digits - floor(log10($value * -1)) - 1;
} else {
$decimalPlaces = $digits - floor(log10($value)) - 1;
}
$answer = round($value, $decimalPlaces);
return $answer;
}
Это даст следующее:
0,0001234567 возвращает 0,0001235
123456,7 возвращает 123500
Однако значение, например от 10 до 4 значимых цифр, следует строго представлять как 10,00, чтобы обозначить точность, с которой это значение известно.
Если это желаемый результат, вы можете использовать следующее:
function sigFig($value, $digits)
{
if ($value == 0) {
$decimalPlaces = $digits - 1;
} elseif ($value < 0) {
$decimalPlaces = $digits - floor(log10($value * -1)) - 1;
} else {
$decimalPlaces = $digits - floor(log10($value)) - 1;
}
$answer = ($decimalPlaces > 0) ?
number_format($value, $decimalPlaces) : round($value, $decimalPlaces);
return $answer;
}
Теперь 1 отображается как 1.000
С небольшой модификацией возможного дубликата ответ Тодда Чаффи:
public static function roundRate($rate, $digits)
{
$mod = pow(10, intval(round(log10($rate))));
$mod = $mod / pow(10, $digits);
$answer = ((int)($rate / $mod)) * $mod;
return $answer;
}
Чтобы sigFig(0.9995, 3) выводил 1.00, используйте
if(floor(log10 ($ value))!== floor(log10(round ($ value, $decimalPlaces)))) {$decimalPlaces--;}
Указанная строка кода должна быть размещена перед объявлением $ answer.
Если input $value отрицательный, установите флаг и удалите знак в начале функции, например:
if ($ value <0) {$flag = 1;} $ value = ltrim ($ value, "-");
Затем прямо перед возвратом $ answer определите, установлен ли флаг, и, если да, восстановите отрицательный знак, например:
if (isset ($ flag)) {$answer = "-". $ answer;}
Наконец, для значений результата с неоднозначным количеством значащих цифр (например, 1000, 12000,...), выразите результат в экспоненциальном представлении в желаемом количестве значащих цифр с помощью sprintf или printf.