Неправильная аппроксимация PHP с помощью printf

Я полностью осведомлен о представлении с плавающей точкой в ​​двоичном формате, поэтому я знаю, что существуют математические «невозможности» при попытке идеально представлять число с плавающей запятой на любом языке программирования. Тем не менее, я ожидаю, что язык программирования будет следовать некоторым хорошо известным и хорошо установленным правилам при рассмотрении аппроксимации.

Сказав это, я прочитал (здесь также и 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!

Спасибо…

Solutions Collecting From Web of "Неправильная аппроксимация PHP с помощью printf"

Вы должны явно округлить значения с помощью 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)); }