PHP中9000000000 % 1000取模返回408而非预期0是什么原因
PHP 大数取模返回非预期结果问题
问题复现
执行如下取模代码时,按数学规则预期结果为0,实际运行返回408:
<?php echo (9000000000 % 1000); ?>
运行效果参考:
根本原因
这个问题是PHP的整型溢出和取模运算符的固有特性导致的:
- PHP原生
%取模运算符仅支持整型运算,运算时会自动将两侧操作数转换为整型处理 - 32位PHP环境中,整型最大值
PHP_INT_MAX为2147483647(即2^31-1),代码中的9000000000远超过这个上限,PHP会自动将其转换为浮点数存储 - 浮点数存在精度边界,大数值转浮点数时会出现精度丢失,存储的数值和原始值存在偏差,最终取模运算就得到了错误的408
即使是64位PHP环境,当运算值超过64位整型上限9223372036854775807时,同样会触发这个问题。
解决方案
根据场景选择以下任意一种方案即可:
- 用BCMath扩展提供的高精度取模函数
bcmod(),这是最通用的方案,支持任意精度的大数运算,不会出现精度丢失。注意大数参数要用字符串形式传入,避免传参前就被PHP转成浮点数丢失精度:
<?php echo bcmod('9000000000', '1000'); // 正确输出0 ?>
- 如果只是计算对10/100/1000这类10的N次幂取模(即取末尾N位),可以直接用字符串截取实现,不需要依赖扩展:
<?php $num = '9000000000'; echo intval(substr($num, -3)); // 取最后3位转整数,输出0 ?>
内容的提问来源于stack exchange,提问作者Waza_Be
相关产品推荐
相关产品推荐

