Этот код:
echo (40 * (10 / 100 + 1)); //44
echo (50 * (10 / 100 + 1)); //55
echo ceil(40 * ((10 / 100) + 1)); //44
echo ceil(50 * ((10 / 100) + 1)); //56 (!)
Я думаю, что «56» по причине с плавающей запятой (55.0000000001 => 56), но я не могу понять, почему для «40» результат «44», а не «45»
55 на самом деле не 55. Вы можете легко это проверить:
<?php
$x = (40 * (10 / 100 + 1)); // 44
$y = (50 * (10 / 100 + 1)); // 55
echo '$x == 44: ' . ($x == 44 ? 'True' : 'False') . "\n";
echo '$y == 55: ' . ($y == 55 ? 'True' : 'False') . "\n";
echo '$y > 55: ' . ($y > 55 ? 'True' : 'False') . "\n";
echo $y - 55;
Урожайность:
$x == 44: True
$y == 55: False
$y > 55: True
7.105427357601E-15
Как видите, разница крошечная (7,1 * 10 ^ -15), но она все равно делает ее больше 55, поэтому ceil
округлю это.
Причина, по которой вы просто видите 55
это потому, что эхо это преобразует поплавок в строку:
Преобразование строки автоматически выполняется в области выражения, где требуется строка. Это происходит при использовании функций echo или print или при сравнении переменной со строкой.
Для этого преобразования стандартное усечение будет отрезать цифры в некоторой точке. Это настраивается precision
параметр конфигурации и по умолчанию 14. Вы можете избежать этого поведения, используя sprintf
с пользовательской точностью:
echo sprintf('%.50f', $y);
// 55.00000000000000710542735760100185871124267578125000
Нам нужно заметить Точность с плавающей точкой
http://php.net/manual/en/language.types.float.php
Рациональные числа, которые точно представимы как числа с плавающей точкой
числа в базе 10, такие как 0,1 или 0,7, не имеют точного
представление в виде чисел с плавающей точкой в базе 2, которая используется
внутренне, независимо от размера мантиссы. Следовательно, они не могут быть
конвертируется в их внутренние двоичные аналоги без небольшой потери
точности. Это может привести к сбивающим с толку результатам: например,
Этаж ((0,1 + 0,7) * 10) обычно возвращает 7 вместо ожидаемых 8,
так как внутреннее представление будет что-то вроде
+7,9999999999999991118 ….
И это ответы на вопрос Почему мои номера не складываются? http://floating-point-gui.de/ . Объясните кратко, почему вы получаете этот неожиданный результат