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

时间:2016-01-25 15:19:29

标签: php serialization floating-point floating-accuracy

我正在写一个serialize()解析器/验证器,我碰到了这个(有些出乎意料的行为):

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

输出:

  

序列化(875.6745)=== d:875.67449999999997;

     

(float)“875.67449999999997”=== 875.6745

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

我应该担心吗?

1 个答案:

答案 0 :(得分:1)

简短回答:你几乎肯定不用担心。

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

没有浮点数875.6745。当您输入数字时,它将转换为IEEE754二进制64(当今大多数计算机上的a.k.a C double)格式,将其舍入为:

875.6744999999999663486960344016551971435546875

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

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

(从技术上讲,PHP says that the size of the float is platform dependent,但除非您正在处理30 year old hardware,否则您不必担心)。