PHP ceil функция странное поведение? - PullRequest
4 голосов
/ 25 ноября 2011

Может кто-нибудь объяснить это?

echo ceil( 20.7 * 100 ); // returns 2070
echo ceil( 2070 );       // returns 2070

все ОК и логично, но

echo ceil( 40.7 * 100 ); // returns 4071
echo ceil( 4070 );       // returns 4070

не ОК и не логично ...

Почему эта разница?

Спасибо

Ответы [ 3 ]

6 голосов
/ 25 ноября 2011

Удивительный мир чисел с плавающей запятой:

printf("%.18f\n", 40.7*100);

//prints 4070.000000000000454747

printf("%.18f\n", 20.7*100);

//prints 2070.000000000000000000

Короче говоря: числа с плавающей запятой не могут точно представлять все рациональные числа.В частности, ни 407/10, ни 207/10 не могут быть представлены точно, и поэтому результат целочисленного преобразования всегда имеет неопределенность в одну единицу.

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

3 голосов
/ 25 ноября 2011

Ошибки с плавающей точкой.40,7 не могут быть представлены точно в плавающем.Это будет что-то вроде 40.700000001 или что-то в этом роде.Когда вы * 100 и закрыли его, оно округляется до 4071.

0 голосов
/ 25 ноября 2011

Проблема с числами с плавающей запятой ... Вы можете решить эту проблему с помощью чего-то вроде:

echo ceil( (int) (40.7 * 100) );
...