2013-12-24 1 views
7

Не могли бы вы объяснить, что здесь происходит?Почему PHP-моделирование ведет себя так? (int) неверное округление чисел?

echo (18.99 * 100); // output: 1899 

echo (int)(18.99 * 100); // output: 1898 

Единственное, что я могу, возможно, думать о том, что на самом деле 1899 +1898,999999999999 или что-то и PHP является преобразование его в качестве части echo каким-то образом? Если это так, почему? Если нет, то в чем причина этого странного поведения?

+0

ну, считаете правильным. int - обрезка десятичной части, и она связана с представлением с плавающей запятой. прочитайте http://en.wikipedia.org/wiki/Floating_point – galchen

+0

Это своего рода. Вы столкнулись с проблемой точности с плавающей точкой. http://stackoverflow.com/questions/14587290/can-i-rely-on-php-php-ini-precision-workaround-for-floating-point-issue – bcmcfc

+0

Вы не можете рассчитывать на точность чисел с плавающей запятой, если только вы только когда-либо используете полномочия двух или кратных. Во-вторых, вы не можете представить число как (целое число) * 2^(целое число), вы ввели ошибку округления. – cHao

ответ

5

из руководства:

При преобразовании из плавающей точкой в ​​целое, число будет округлено к нулю.

Если поплавок выходит за границы целого числа (usually +/- 2.15e+9 = 2^31 on 32-bit platforms and +/- 9.22e+18 = 2^63 on 64-bit platforms), результат не определен, так как float не имеет достаточной точности для получения точного целочисленного результата. Никакого предупреждения, даже уведомление не будет опубликовано, когда это произойдет!

Предупреждение

Никогда не приводите неизвестную дробь к целому, так как это иногда может привести к неожиданным результатам .

<?php 
echo (int) ((0.1+0.7) * 10); // echoes 7! 
?> 

Read here

Кроме того, рациональные числа, которые точно представить в виде чисел с плавающей точкой по основанию 10, как 0.1 или 0.7, не имеют точного представления в качестве чисел с плавающей точкой в ​​основании 2, которое используется внутренне, независимо от размера мантиссы. Следовательно, они не могут быть преобразованы в их внутренние двоичные копии без небольшой потери точности. Это может привести к неожиданным результатам: например, пол ((0,1 + 0,7) * 10), как правило, возвращают 7 вместо ожидаемого 8, так как внутреннее представление будет что-то вроде 7,9999999999999991118 ....

в ваш случай может быть 18.99*100=1898.999999999999772626324556767940521240234375, поэтому int усечен до 1898 года.

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

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