Курск
Хотел с помощью php кое-что посчитать и столкнулся с проблемой, вот даже при такой простейшей арифметической операции не выдает в итоге ноль:
echo 111.01-100.02-10.99;
а выдает 8.881784197E-015
Это нормально? Почему так?
Ganzal
ну почему не ноль? ноль, просто очень высокой четкости. это особенность хранения чисел с плавающей точкой, свойственная практически всем языкам программирования.
YSandro
А попробуй на JS:
Код (PHP):
alert(111.01—100.02—10.99);Выдает 8.881784197001252e-15
Курск
JS не знаю.
Однако если сделать так:
echo 11.01-0.02-10.99;
или так:
echo 38.37 — 22.13 — 16.24;
php выдает четко 0.
что за дела…
denis01
Курск
https://secure.php.net/manual/ru/ref.gmp.php
Курск
уdenis01, блин, как все сложно… Хотел по быстрому посчитать, а надо кучу функций учить и еще что-то ставить…
YSandro
GMP требует установки.
Можно через BCMath, она встроена в PHP. Только числа должны быть в виде строк.
Курск
Ладно бы было деление и иррациональность в дроби, но это же простое сложениевычитаение…
YSandro
Можно просто округлить к нужной точности.
mkramer
Курск, точной вещественной арифметики не бывает вообще в компьютере. Вещественные числа, если они как числа, считает сам процессор, поэтому это не зависит от языка программирования. Потом, вещественные числа тоже в двоичной системе хранятся внутри компьютера, а конечная дробь в десятичной системе может быть бесконечной в двоичной
Курск
YSandro обычно использую округление если есть умножение или деление, а тут стало неожиданностью, что даже при сложении и вычитании надо округлять.
Ну раз это всё нормально, то спасибо за посдказки, просветили. Буду округлять даже в случаях сложения и вычитания.
Ganzal
и еще разок. это способ хранения япом числа в памяти. даже банальное $a = 10.0 в мозгах компа может выглядеть как 10.00000000000000000001 или 9.99999999999999999999999999971 например. так что дело не в операциях которые производятся над значениями, дело в самих значениях. если раньше проблемы не было то это можно смело назвать «прокатывало». и кстати поэтому же такие числа не используют при работе с денежными единицами — миллиардная доля копейки через сто миллиардов операций станет рублём.
Курск
Ganzal, спасибо за пояснение. Я вот как раз деньги и хотел считать
artoodetoo
а вот еще баянчег:
Код (PHP):
echo 0.1 + 0.7; // выведет «0.8»)))
вещественные числа такие коварные!
iNEEdhLw
если забыть про потерю точности из-за двоичного представления, то это сродни черной магии.
artoodetoo
Может в PHP 8 введут базовый тип currency, ну или стадартный класс. Пользы было бы больше, чем от goto! )))
Ну а пока люди создают свои классы: https://www.google.ru/search?q=php+currency+class
artoodetoo
currency не появился
молитвы не были услышаны
Похожие записи:
- Скрипт для распаковки архивов разного типа
- Поменять местами столбцы и строки в таблице
- не работает проверка равенства
- Advent Of Code 2020, день 1, найдите желаемую сумму и умножьте слагаемые
- Определите самый длинный сегмент целых чисел в инклюзивном диапазоне, который не содержит плохого числа, используя Python