PHP中strlen()函数对浮点数及浮点数运算结果返回不同长度的原因解析
为什么
23.0000000000001*10的strlen()返回3而非15? 这事儿核心还是双精度浮点数的精度限制加上PHP自动类型转换的逻辑在搞鬼,咱们一步步拆明白:
先理清前两个例子的本质
- 第一个例子里的
23.000000000001:这个数的有效数字是14位(2、3,加上12个0和最后一位的1),刚好落在双精度浮点数的精确表示范围内(双精度能精确存储15-17位十进制有效数字)。所以PHP把它转成字符串时,能完整保留"23.000000000001"这个形式,长度自然是15。 - 第二个例子的
23.0000000000001:这个数的有效数字是15位,超出了双精度浮点数的精确存储上限。计算机没法精准存下这个数,只能把它舍入到最接近的可表示浮点数——也就是23.0。转成字符串就是"23",strlen()自然返回2。
重点拆解第三个例子:23.0000000000001*10
你可能误以为是先保留23.0000000000001再做乘法,但实际上,代码执行的第一步,23.0000000000001就已经被舍入成23.0了。
你的代码等价于:
$original = 23.0 * 10; // 结果是230.0 echo strlen($original); // 输出3,因为字符串是"230"
根本不存在230.000000000001这个中间值——原始的23.0000000000001从一开始就没法被精确存储,早就变成23.0了,乘以10之后自然是230.0,转成字符串就是三位长度。
额外提个避坑建议
如果是处理需要精确计算的小数场景(比如金额、高精度计量),别用普通浮点数,建议用PHP的BCMath扩展或者Decimal类型,它们能提供高精度的十进制运算,避免这种隐形舍入问题。
内容的提问来源于stack exchange,提问作者Henlo Wald
相关产品推荐
相关产品推荐

