2015-08-26 3 views
-5

Почему у Земли $ r2 есть значение 2027?Что здесь делает PHP? Ошибка?

$r1 = ceil(10.26 * 100); //equals 1026 - CORRECT. 

$r2 = ceil(20.26 * 100); //equals 2027 - WRONG! 

(я предполагаю, что по какой-то причине (20,26 * 100) не приводит к точному числу, но ПОЧЕМУ ??!? Разве это не ошибка?

+5

См. [Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – RiggsFolly

+0

Вы умножаетесь на плавающие номер точки. Почему это приведет к целому числу? –

+0

Можно было бы ожидать целое число, потому что он вызывает ceil, который возвращает целое число. – a2800276

ответ

1

Числа с плавающей точкой ведут себя неожиданным образом (Статья Google «Каждый компьютерный ученый должна знать о плавающей точке»).

В принципе, компьютер не имеет возможности точно работать со значениями с плавающей запятой, поэтому вам всегда нужно ожидать некоторых приближений в ваших расчетах (что, кстати, почему вы НИКОГДА не представляете деньги как плавающие точки).

В вашем случае, результат:

20,26 * 100

является

2026,0000000000002

ceil раундов до ближайшего целого числа, которое является 2027, так что ответ является правильным.

0

Нет, это не ошибка. Это связано с точностью чисел с плавающей запятой. Как вы, возможно, знаете, компьютер является дискретной машиной. Реальные числа имеют бесконечное число чисел между двумя действиями: компьютер не может обрабатывать числа до бесконечности или даже все числа от 0,00 до 0,01, например: между ними существует бесконечное количество реалов.

Ваш компьютер обрабатывает реляты дискретно: все числа округляются до ближайшего представляемого числа с плавающей запятой; поэтому числа с плавающей запятой всегда содержат ошибку представления (за исключением случаев, когда реальный, который вы ищете, может быть представлен точно). Все небольшие ошибки в расчетах учитывают окончательную ошибку. Это то, что происходит в вашем случае. Для получения дополнительной информации и математического объяснения: https://en.wikipedia.org/wiki/Floating_point

Для примера в реальной жизни. Просто запустите этот фрагмент кода PHP и посмотрите, что произойдет:

$sum = 0.0; 
for ($i = 0; $i < 1000; $i++) { 
    $sum += 0.1; 
} 

Вы ожидаете, что сумма станет равной 100, не так ли?

Еще один совет о вашей части кода: если вы используете ceil() для получения целого числа, вам лучше использовать функцию round().

+0

Что это за демонстрация? Он выводит ровно один. https://eval.in/422673 – chris85

+0

Вы правы. Я не проверял. Я изменил его. Это показывает проблему :) – Keugels

 Смежные вопросы

  • Нет связанных вопросов^_^