在 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,您无需担心)。
我正在写一个 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,您无需担心)。