在 PHP 中序列化浮点数 - 意外结果

Serializing Floats in PHP - Unexpected Results

我正在写一个 serialize() parser/validator,并且我 运行 跨越了这个(有点意外的行为):

$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

当我序列化一个浮点数时,存储的值并不真正匹配输入,但是,当序列化的字符串被重新float编辑时,值再次匹配...

我应该担心吗?

简短回答:您几乎可以肯定不需要担心。

长答案:PHP 只是打印足够的数字以确保它可以正确地准确读回数字。

没有浮点数875.6745。当您输入数字时,它会转换为 IEEE754 binary64(a.k.a C double 在当今大多数计算机上)格式,四舍五入为:

875.6744999999999663486960344016551971435546875

当你序列化它时,它不会打印这个数字(也不需要):相反它只保存 17 位数字,which is enough to ensure that it can read back the value exactly.

这种转换在今天的大多数硬件上应该是一致的,你不必担心 32 位和 64 位平台:这对浮点数完全没有影响(我们有 "native" 64自 16 位 8086 以来位浮动。

(从技术上讲,PHP says that the size of the float is platform dependent, but unless you're dealing with 30 year old hardware,您无需担心)。