floor向下取整、ceil向上取整、round四舍五入;round支持小数位控制,floor/ceil不支持且易受浮点误差影响;精确计算应使用BCMath或整数运算。

PHP 中 floor、ceil、round 的本质区别
这三个函数看起来都“处理小数”,但行为完全不同,选错就出 bug:floor 是向下取整(往负无穷方向),ceil 是向上取整(往正无穷方向),round 才是四舍五入(默认到个位)。
比如 floor(2.9) 得 2,ceil(2.1) 得 3,round(2.5) 得 3(注意 PHP 默认采用“四舍六入五成双”规则,但常见版本中多数表现为传统四舍五入)。
用 round 隐藏小数位的正确姿势
想保留 2 位小数并四舍五入?直接传第二个参数:round(3.14159, 2) → 3.14round(3.145, 2) → 3.15(不是 3.14)
但要注意:如果输入是字符串如 "3.14",PHP 会自动转 float,但精度可能丢失(尤其超 15 位数字时)。
- 第二个参数可为负数,如 round(1234.56, -2) → 1200
- 不要混用 number_format 和 round 做精度控制——前者是格式化输出,返回字符串;后者才是数值计算
floor 和 ceil 为什么不能直接替代 round
它们不支持小数位控制,强行“模拟”容易翻车:
- 想保留 1 位小数后向下取整?别写 floor($x * 10) / 10 —— 浮点误差会让 floor(1.28 * 10) 变成 floor(12.799999999999999) → 12,结果变成 1.2
- 更稳妥的是先 round($x, 1) 再 floor 或 ceil,比如:
$x = 1.28;
$rounded = round($x, 1); // 1.3
floor($rounded * 10) / 10; // 1.3
-
ceil 在处理负数时行为反直觉:ceil(-2.1) 是 -2,不是 -3
浮点精度问题让所有函数都可能失准
PHP 的 float 是 IEEE 754 双精度,很多十进制小数无法精确表示:var_dump(0.1 + 0.2 === 0.3); // bool(false)
这意味着:
- round(0.1 + 0.2, 1) 可能返回 0.30000000000000004,再格式化才好看
- 真正需要精确小数运算(如金额),别依赖这三个函数,改用 bcadd、bcmul 等 BCMath 函数,或把金额转成整数分来算
- 如果只是前端展示,sprintf('%.2f', $x) 比 round 更可控(它按字符串截断+四舍五入)











