Почему в итоге не ноль?

Курск

Хотел с помощью php кое-что посчитать и столкнулся с проблемой, вот даже при такой простейшей арифметической операции не выдает в итоге ноль:

echo 111.01-100.02-10.99;

а выдает 8.881784197E-015

Это нормально? Почему так?

 

Ganzal

ну почему не ноль? ноль, просто очень высокой четкости. это особенность хранения чисел с плавающей точкой, свойственная практически всем языкам программирования.

 

YSandro

А попробуй на JS:

Код (PHP):
  1. alert(111.01100.0210.99);

Выдает 8.881784197001252e-15

 

Курск

JS не знаю.
Однако если сделать так:
echo 11.01-0.02-10.99;
или так:
echo 38.37 — 22.13 — 16.24;
php выдает четко 0.
что за дела…

 

denis01

Курск

уdenis01, блин, как все сложно… Хотел по быстрому посчитать, а надо кучу функций учить и еще что-то ставить…

 

YSandro

GMP требует установки.
Можно через BCMath, она встроена в PHP. Только числа должны быть в виде строк.

 

Курск

Ладно бы было деление и иррациональность в дроби, но это же простое сложениевычитаение…

 

YSandro

mkramer

Курск, точной вещественной арифметики не бывает вообще в компьютере. Вещественные числа, если они как числа, считает сам процессор, поэтому это не зависит от языка программирования. Потом, вещественные числа тоже в двоичной системе хранятся внутри компьютера, а конечная дробь в десятичной системе может быть бесконечной в двоичной

 

Курск

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

Ну раз это всё нормально, то спасибо за посдказки, просветили. Буду округлять даже в случаях сложения и вычитания.

 

Ganzal

и еще разок. это способ хранения япом числа в памяти. даже банальное $a = 10.0 в мозгах компа может выглядеть как 10.00000000000000000001 или 9.99999999999999999999999999971 например. так что дело не в операциях которые производятся над значениями, дело в самих значениях. если раньше проблемы не было то это можно смело назвать «прокатывало». и кстати поэтому же такие числа не используют при работе с денежными единицами — миллиардная доля копейки через сто миллиардов операций станет рублём.

 

Курск

Ganzal, спасибо за пояснение. Я вот как раз деньги и хотел считать :)

 

artoodetoo

а вот еще баянчег:

Код (PHP):
  1. echo 0.1 + 0.7; // выведет «0.8»
  2. var_dump(0.1 + 0.7 == 0.8); // выведет «bool(false)»
  3.  

)))
вещественные числа такие коварные!

 

iNEEdhLw

если забыть про потерю точности из-за двоичного представления, то это сродни черной магии.

 

artoodetoo

Может в PHP 8 введут базовый тип currency, ну или стадартный класс. Пользы было бы больше, чем от goto! )))
Ну а пока люди создают свои классы: https://www.google.ru/search?q=php+currency+class

 

artoodetoo

currency не появился :( молитвы не были услышаны

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *