Я полностью осведомлен о представлении с плавающей точкой в двоичном формате, поэтому я знаю, что существуют математические «невозможности» при попытке идеально представлять число с плавающей запятой на любом языке программирования. Тем не менее, я ожидаю, что язык программирования будет следовать некоторым хорошо известным и хорошо установленным правилам при рассмотрении аппроксимации.
Сказав это, я прочитал (здесь также и stackoverflow), что printf в PHP, вероятно, является лучшим способом «правильно усекать / приближать» число, и – снова – я полностью осведомлен, и я могу легко кодировать однострочную функцию чтобы дать мне «идеальное» приближение. Это просто, чтобы избежать ответов типа «почему бы вам не использовать XXX или сделать YYY?».
Попробуй это:
for($i=0; $i<10; $i++) { $k = 1.50 + $i/1000; printf("%f %.2f<br>", $k, $k); }
Это результат:
1,500000 1,50
1,501000 1,50
1,502000 1,50
1,503000 1,50
1,504000 1,50
1,505000 1,50
1,506000 1,51
1,507000 1,51
1,508000 1,51
1,509000 1,51
Как вы можете легко видеть, 1.504 (правильно) напечатан как 1.50, а 1.506 (правильно) напечатан как 1.51. Но почему 1.505 печатается как 1.50 ?! Он ДОЛЖЕН БЫТЬ 1.51, а не 1.50!
Спасибо…
Вы должны явно округлить значения с помощью round
функции, чтобы вы могли использовать mode
аргумента со значениями:
PHP_ROUND_HALF_UP -- Round val up to precision decimal places away from zero, when it is half way there. Making 1.5 into 2 and -1.5 into -2.
PHP_ROUND_HALF_DOWN -- Round val down to precision decimal places towards zero, when it is half way there. Making 1.5 into 1 and -1.5 into -1.
функция:
float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
см. полное описание:
http://php.net/manual/en/function.round.php
РЕДАКТИРОВАТЬ:
for($i=0; $i<10; $i++) { $k = 1.50 + $i/1000; printf("%f %f<br>", $k, round($k,2,PHP_ROUND_HALF_UP)); }