Задать вопрос

Почему PHP выполняет математические операции неправильно?

Здравствуйте! Выполняю простую математическую операцию и получаю следующий результат:

$format = (580000000 / 1000000000); // 0.58

var_dump($format * 100); // float(57.99999999999999)


По логике $format = 0.58, значит ответ должен быть при 0.58*100 = 58, но почему тут такой результат 57.99999999999999 ?
  • Вопрос задан
  • 9578 просмотров
Подписаться 3 Простой 2 комментария
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 2
Коротко - потому что IEEE 754

Выполняет он математические операции правильно, но некоторые числа компьютер просто не способен представить со 100% точностью, тк для них нужно было бы бесконечное количество памяти.

Точно также, как мы не можем записать все цифры числа 1/3 в десятичной системе, точно также и компьютер иногда не может записать все цифры в двоичной.

Если ты работаешь с деньгами, то тогда используй то, что делают все банки - представляй суммы денег не как дробные числа, а как целые. Например место 1.5 рублей записывай как 150 копеек. Запятую добавишь при выводе человеку.
btw тут в комментах пишут, что для денег тоже есть паттерн по-лучше конкретно для php.

Если при делении у тебя получилось дробное количество копеек - округляй так, как велит закон.

Если ты делаешь какие-то математические вычисления - возможно тебе нужны рациональные числа.
Не знаю, что обычно для этого в пхп используют, но нагуглил https://github.com/webgriffe/rational
https://github.com/markrogoyski/math-php

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

Если тебе критически важна скорость, а точность - не так важна, то оставайся на IEEE754 и просто округляй то N значимых цифр (обычно больше 5 цифр мало кому нужно)
Ответ написан
Vamp
@Vamp
Потому что типом данных double нет возможности представить число 0.58. Поэтому компьютер берёт наиболее близкое к 0.58 число, которое double может выразить.

Если вам нужны точные вычисления, то следует воспользоваться специальными функциями:

$format = bcdiv("580000000", "1000000000", 2); // "0.58"

var_dump(bcmul($format, "100")); // string(2) "58"


Существует даже специальный сайт, рассказывающий о данной особенности математики чисел с плавающей запятой: https://0.30000000000000004.com/
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@Everything_is_bad
Нет, он выполняет правильно, почти все ЯП так выполнят операции с float, гугли проблему с точностью вычислений
Ответ написан
Комментировать
На сколько я помню, эта проблема не с php, эта проблема со всеми языками программирования.
Там что-то связано с процессорами и памятью.
Ответ написан
@semivi
Здесь давал развёрнутый ответ
https://www.mql5.com/ru/forum/1111/page2623#commen...
Ответ написан
Комментировать
@eurolt
Аааааааа это разрыв))))))))))))))))) PHP не правильно вычисляет))))))))))))))))) Горе программисты, учите мат часть
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽