PHP 8 десятичная точка с плавающей запятой отличается от PHP 7

#floating-point #precision #php-7.4 #php-8 #php-8.1

#с плавающей запятой #точность #php-7.4 #php-8 #php-8.1

Вопрос:

Я обновил некоторые учетные скрипты до PHP 8.1, однако я получаю неправильные плавающие точки.

Я перебираю несколько транзакций дебет / кредит, и баланс равен 0, однако в конце, когда я пытаюсь сравнить с нулем, он не работает с == 0 и === 0

После нескольких отладок я узнал:

 <?php
var_dump(1097.5 - 835.7);
 

возвращает значение с плавающей запятой (261.79999999999995)

И та же строка в PHP 7 возвращает значение с плавающей запятой (261.8)

Это можно легко протестировать с помощью этой песочницы

Итак, мне было интересно, есть ли какие-либо настройки, которые я могу изменить в своих конфигурациях PHP, чтобы убедиться, что я получаю те же плавающие результаты, что и раньше, без необходимости округлять на каждом этапе в сотнях скриптов?

Комментарии:

1. «однако я получаю неправильные плавающие точки». —> Возможно, теперь вы получаете лучший результат, но ваш код полагался на предыдущий менее правильный результат. Лучше использовать денежный расчет с наименьшей единицей (например, с пенни, а не с долларом).

2. К ВАШЕМУ сведению, 3v4l.org это отличная песочница для сравнения поведения в разных версиях, поскольку она запускается в каждой версии и сравнивает результат для вас. Например: 3v4l.org/1MZST

Ответ №1:

ПРИМЕЧАНИЯ ПО ОБНОВЛЕНИЮ PHP 8.0:

var_dump() и debug_zval_dump() теперь будут печатать числа с плавающей запятой, используя serialize_precision, а не precision . В конфигурации по умолчанию это означает, что числа с плавающей запятой теперь печатаются с полной точностью с помощью этих функций отладки.

Итак, вы можете изменить это

 ini_set('serialize_precision', 16);
 

https://3v4l.org/uOAPD#v8.1rc3

Однако я сомневаюсь, что это ваша настоящая проблема! поскольку это изменение затрагивает только «эти функции отладки», а также функции serlization, такие как serialize , json_encode

Комментарии:

1. Спасибо, я думаю, это помогло встать на правильный путь для отладки моей проблемы. Я изменил строку на ini_set(‘serialize_precision’, ini_get(«точность»)); «точность» равна 14, а не 16