round() 返回 float 类型,如 round(5.0) 得 5.0 而非 int 5,导致 json 编码为 5.0、类型严格比较失败或 typeerror,须显式转 (int) 或 intval();php 8.3+ 新增 $mode 参数影响舍入逻辑与精度行为。

round() 返回的是 float,不是 int
PHP 的 round() 函数默认返回 float 类型,哪怕你四舍五入的是整数,比如 round(5.0) 也返回 5.0 而不是 5。这在严格类型比较(===)、JSON 编码、数据库写入或强类型函数参数中会出问题。
常见错误现象:
– json_encode(['num' => round(4.7)]) 输出 {"num":5.0}(而不是 5)
– 传给声明了 int 类型的函数时触发 TypeError
– 和 is_int() 判断结果为 false
- 必须显式转换:用
(int) round($x)或intval(round($x)) - 注意负数截断差异:
(int) round(-2.6)得-3(正确),但(int) -2.6直接截断得-2,别混淆 - PHP 8.1+ 支持
round($x, 0, PHP_ROUND_HALF_UP),但返回值类型不变,仍需转型
PHP 8.3+ 新增的 round() 第三个参数影响精度行为
从 PHP 8.3 开始,round() 支持第三个参数 $mode,它不只是控制舍入方向(如 PHP_ROUND_HALF_DOWN),还会影响中间值的处理逻辑——尤其当小数位数为 0 且输入是浮点数时,某些模式可能暴露底层 IEEE 754 表示误差。
使用场景:
– 需要银行家舍入(偶数舍入)时用 PHP_ROUND_HALF_EVEN
– 处理金额计算时避免系统性偏差
立即学习“PHP免费学习笔记(深入)”;
- 旧版本($mode 参数会被忽略
- 即使指定了
$mode,返回值仍是float,转型步骤不能省 - 测试时别只用
round(1.5),试试round(1.5000000000000002)—— 浮点表示误差会让结果变成2.0或1.0,取决于$mode
替代方案:intval() / (int) / floor() / ceil() 不等于 round()
很多人误以为 (int) 或 intval() 是“四舍五入”,其实它们只是向零截断;floor() 和 ceil() 是向下/向上取整。这些函数行为完全不同,混用会导致逻辑错误。
常见错误现象:
– (int) 2.9 → 2(不是 3)
– floor(−2.1) → −3(不是四舍五入)
– round(−2.5, 0, PHP_ROUND_HALF_DOWN) → −2.0,而 floor(−2.5) → −3.0
- 需要四舍五入就坚持用
round(),别图快换函数 - 如果目标是“取整到最近的整数”,
round($x)是唯一语义正确的选择 - 性能上差别可忽略,不用为这点微秒去“优化”成
(int)($x + 0.5)—— 这在负数和边界值上完全错误
JSON 和数据库写入前务必检查类型
PHP 的 JSON 扩展对 float 和 int 的序列化行为不同:5 输出为 5,5.0 输出为 5.0。MySQL 的 INT 字段虽能自动转,但 PostgreSQL 会报错,API 消费方也可能因字段类型不一致拒绝解析。
- 写入前统一做
(int) round($x),别依赖隐式转换 - 批量处理时加个类型断言:
assert(is_int($val), 'Expected int after rounding')(开发环境) - 用
var_dump()检查实际类型,别只看echo输出——echo 5.0和echo 5看起来一样
最常被忽略的一点:round() 的返回类型不随输入类型改变。哪怕你传进去的是 int,返回的还是 float。这个设计从 PHP 4 就定死了,改不了,只能手动兜底。











