php Опасность приведения (конвертирования) дробных чисел к целым (float, int)
Primary tabs
В php "справедливо" равенство (далее знак равно в математическом смысле):
(int) ((0.1+0.7)*10) == 7
-- т.е. если привести левую часть к целому (а это делается путём отбрасывания дробной части)
Это можно проверить, запустив код вида:
echo ((int) (((int)((0.1+0.7)*10)) == 7)); // получим 1 т.е. true
Почему это происходит?
Это происходит потому, что десятичная дробь 0.8 в двоичной системе представляется бесконечной дробью (а хранится в памяти компьютера это число именно в двоичной форме), вот её первые цифры:
0.7999992370605469
-- так она выглядит, если эту бесконечную двоичную дробь переводить в десятичную.
А потому по факту после вычисления
(0.1+0.7)*10
мы получаем не 8 (что казалось бы "логичным"), а:
printf("%.53F\n", (0.1+0.7)*10); // т.е. 7.99999999999999911182158029987476766109466552734375000
Математическое основание -- почему бесконечная дробь
Вывод
Полагаться на простое приведение типа в данном случае нельзя. "Правильное" же приведение зависит от конкретной задачи.
- Log in to post comments
- 2732 reads