floor() 实现真正向下取整,负数时区别于(int)截断;其返回float是为保持大数精度,并非bug。

用 floor() 实现向下取整,不是强制类型转换
直接 (int) 或 intval() 会截断小数部分,对正数看起来像向下取整,但负数时是「向零取整」——比如 intval(-3.7) 得 -3,而向下取整应得 -4。真正向下取整必须用 floor()。
-
floor(3.7)→3 -
floor(-3.7)→-4 -
(int)-3.7→-3(错误结果) -
floor()返回 float 类型,需再转 int 才得整型值:(int)floor(3.7)
为什么 floor() 返回 float 而不是 int
PHP 的浮点数精度限制导致大数(如超过 9007199254740992)无法被 int 精确表示,floor() 为保持数值完整性,统一返回 float。这不是 bug,是设计选择。
- 对普通业务数字(
),<code>(int)floor($x)安全 - 若 $x 可能极大(如时间戳毫秒级大数),直接用
floor($x)结果即可,别强转int,否则可能溢出变0或负值 - 注意:PHP 8.1+ 对超大 float 转 int 会抛
ValueError,而floor()本身不抛错
替代方案对比:round($x, 0, PHP_ROUND_HALF_DOWN) 不行
round() 是四舍五入变体,不是向下取整。即使指定 PHP_ROUND_HALF_DOWN,它只影响 .5 的处理,对 3.9、-2.1 等仍按常规舍入逻辑,完全不等价于 floor()。
-
round(3.9, 0, PHP_ROUND_HALF_DOWN)→4.0(不是3) -
round(-2.1, 0, PHP_ROUND_HALF_DOWN)→-2.0(不是-3) - 唯一安全的向下取整入口只有
floor(),别绕弯
浮点误差导致 floor() 出错的典型场景
计算结果本该是整数(如 0.1 + 0.2 + 0.7),但因二进制浮点误差变成 0.9999999999999999,floor() 就会错判为 0 而非 1。
立即学习“PHP免费学习笔记(深入)”;
- 常见于金额计算、百分比累加、循环计数器
- 解决方法:先用
round($x, 10)消除微小误差,再floor():floor(round($x, 10)) - 或改用整数运算:把元换算成分,全程用 int 处理
- 不要依赖
floor($x + 1e-10)这类魔数偏移,不可靠且掩盖问题本质
floor(),而是忘了它返回 float、忘了浮点误差会让“本该整”的数掉下去一格——这两个点卡住过太多人。











