Сериализация — Сериализация чисел с неожиданными результатами

Я пишу serialize() парсер / валидатор, и я столкнулся с этим (несколько неожиданное поведение):

$float = 875.6745;
echo "serialize({$float}) === " . serialize($float) . "\n";
echo "(float) \"875.67449999999997\" === " . ((float) "875.67449999999997") . "\n";

Выход:

serialize (875.6745) === d: 875.67449999999997;

(float) «875.67449999999997» === 875.6745

Когда я сериализую число с плавающей запятой, сохраненное значение на самом деле не совпадает с вводом, однако, когда сериализованная строкаfloated, значение снова совпадает …

Должен ли я быть обеспокоен?

1

Решение

Короткий ответ: вам почти наверняка не нужно беспокоиться.

Длинный ответ: PHP просто печатает достаточно цифр, чтобы гарантировать, что он может правильно прочитать число точно.

Нет числа с плавающей запятой 875.6745. Когда вы вводите число, оно преобразуется в двоичный код IEEE754 (a.k.a C double на большинстве компьютеров сегодня) формат, который округляет его до:

875,6744999999999663486960344016551971435546875

Когда вы сериализуете его, он не печатает этот номер (и не нуждается): вместо этого он просто сохраняет 17 цифр, этого достаточно, чтобы обеспечить возможность точного считывания значения.

Это преобразование должно быть согласованным для большинства современных аппаратных средств, и вам не нужно беспокоиться о 32-х и 64-битных платформах: это абсолютно не имеет отношения к числам с плавающей запятой (у нас были «родные» 64-битные операции с 16-битными 8086).

(Технически, PHP говорит, что размер поплавка зависит от платформы, но если вы не имеете дело с 30 лет оборудования, вам не нужно беспокоиться).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]