13、PHP 8.4 新特性 - PHP 8.4:round() 函数中的新舍入模式
在 PHP 8.4 中,round() 函数新增了 舍入模式 的选项,使得开发者能够在四舍五入的过程中,选择不同的舍入行为。这个新增功能为开发者提供了更多的灵活性,特别是在金融计算、精度控制等场景中,能够更精确地控制舍入的方式。
<?php
declare(strict_types=1);
echo round(3.14, precision: 0, mode: PHP_ROUND_HALF_UP) . PHP_EOL; // 3
echo round(3.14, precision: 1, mode: PHP_ROUND_HALF_UP) . PHP_EOL; // 3.1
echo round(3.15, precision: 0, mode: PHP_ROUND_HALF_UP) . PHP_EOL; // 3
echo round(3.5, precision: 0, mode: PHP_ROUND_HALF_UP) . PHP_EOL; // 4
在 PHP 8.4 之前,round() 函数支持四种舍入方法:
-
PHP_ROUND_HALF_UP:当数值正好位于两个整数中间时,远离零的方向进行舍入。例如,1.5 舍入为 2,-1.5 舍入为 -2。常量值为 int(1)。 -
PHP_ROUND_HALF_DOWN:当数值正好位于两个整数中间时,朝向零的方向进行舍入。例如,1.5 舍入为 1,-1.5 舍入为 -1。常量值为 int(2)。 -
PHP_ROUND_HALF_EVEN:当数值正好位于两个整数中间时,向最近的偶数舍入。例如,1.5 和 2.5 都舍入为 2。常量值为 int(3)。 -
PHP_ROUND_HALF_ODD:当数值正好位于两个整数中间时,向最近的奇数舍入。例如,1.5 舍入为 1,2.5 舍入为 3。常量值为 int(4)。
在 PHP 8.4 中,round() 函数新增了以下四种舍入方法:
-
PHP_ROUND_CEILING:将数值向上舍入到最接近且大于该数值的整数。例如,1.1 和 1.5 都舍入为 2,-1.1 和 -1.5 都舍入为 -1。当$precision参数为 0 时,返回值与ceil函数的返回值相同。常量值为 int(5)。 -
PHP_ROUND_FLOOR:将数值向下舍入到最接近且小于该数值的整数。例如,1.1 和 1.9 都舍入为 1,-1.9 和 -1.1 都舍入为 -2。返回值与floor函数的返回值相同。常量值为 int(6)。 -
PHP_ROUND_TOWARD_ZERO:将数值朝向零的方向舍入。例如,1.9 和 1.1 都舍入为 1,-1.9 和 -1.1 都舍入为 -1。常量值为 int(7)。 -
PHP_ROUND_AWAY_FROM_ZERO:将数值远离零的方向舍入。例如,1.1 和 1.9 都舍入为 2,-1.1 和 -1.9 都舍入为 -2。常量值为 int(8)。
以下表格总结了不同舍入模式下示例数值的返回值:
| 数值 | PHP_ROUND_HALF_UP | PHP_ROUND_HALF_DOWN | PHP_ROUND_HALF_EVEN | PHP_ROUND_HALF_ODD | PHP_ROUND_CEILING | PHP_ROUND_FLOOR | PHP_ROUND_TOWARD_ZERO | PHP_ROUND_AWAY_FROM_ZERO |
|---|---|---|---|---|---|---|---|---|
| 0.8 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
| 1.1 | 1 | 1 | 1 | 1 | 2 | 1 | 1 | 2 |
| 1.5 | 2 | 1 | 2 | 1 | 2 | 1 | 1 | 2 |
| 1.9 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | 2 |
| -0.8 | -1 | -1 | -1 | -1 | -0 | -1 | -0 | -1 |
| -1.1 | -1 | -1 | -1 | -1 | -1 | -2 | -1 | -2 |
| -1.5 | -2 | -1 | -2 | -1 | -1 | -2 | -1 | -2 |
| -1.9 | -2 | -2 | -2 | -2 | -1 | -2 | -1 | -2 |
这个表格展示了在不同的舍入模式下,给定数值是如何被舍入的。例如:
-
PHP_ROUND_HALF_UP:当数值正好位于两个整数中间时,远离零的方向进行舍入。 -
PHP_ROUND_HALF_DOWN:当数值正好位于两个整数中间时,朝向零的方向进行舍入。 -
PHP_ROUND_HALF_EVEN:当数值正好位于两个整数中间时,向最近的偶数舍入。 -
PHP_ROUND_HALF_ODD:当数值正好位于两个整数中间时,向最近的奇数舍入。 -
PHP_ROUND_CEILING:将数值向上舍入到最接近且大于该数值的整数。 -
PHP_ROUND_FLOOR:将数值向下舍入到最接近且小于该数值的整数。 -
PHP_ROUND_TOWARD_ZERO:将数值朝向零的方向舍入。 -
PHP_ROUND_AWAY_FROM_ZERO:将数值远离零的方向舍入。
使用 Intl 扩展 NumberFormatter 进行舍入
Intl 扩展中的 NumberFormatter 类也提供了舍入功能,并且额外支持数字的本地化。
NumberFormatter 类同样支持与 round() 函数相同的舍入模式,这些模式可以通过设置对象的属性(NumberFormatter::ROUNDING_MODE)来配置。精度则通过 NumberFormatter::FRACTION_DIGITS 属性来设置:
$formatter = new \NumberFormatter("zh-CN", \NumberFormatter::DECIMAL);
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, 0);
$formatter->setAttribute(\NumberFormatter::ROUNDING_MODE, \NumberFormatter::ROUND_HALFUP);
echo $formatter->format(1.1); // 输出 1
下表显示了每个 round() 舍入模式对应的 NumberFormatter::ROUNDING_MODE 属性值:
| round 模式 | NumberFormatter::ROUNDING_MODE 值 |
|---|---|
| PHP_ROUND_HALF_UP | NumberFormatter::ROUND_HALFUP |
| PHP_ROUND_HALF_DOWN | NumberFormatter::ROUND_HALFDOWN |
| PHP_ROUND_HALF_EVEN | NumberFormatter::ROUND_HALFEVEN |
| PHP_ROUND_HALF_ODD | NumberFormatter::ROUND_HALFODD |
| PHP_ROUND_CEILING | NumberFormatter::ROUND_CEILING |
| PHP_ROUND_FLOOR | NumberFormatter::ROUND_FLOOR |
| PHP_ROUND_TOWARD_ZERO | NumberFormatter::ROUND_DOWN 或 NumberFormatter::ROUND_TOWARD_ZERO |
| PHP_ROUND_AWAY_FROM_ZERO | NumberFormatter::ROUND_UP 或 NumberFormatter::ROUND_AWAY_FROM_ZERO |
NumberFormatter 新增常量
-
NumberFormatter::ROUND_TOWARD_ZERO(值为 int(2)):这是NumberFormatter::ROUND_DOWN的别名,以与round()函数的PHP_ROUND_TOWARD_ZERO模式保持一致。 -
NumberFormatter::ROUND_AWAY_FROM_ZERO(值为 int(3)):这是NumberFormatter::ROUND_UP的别名,以与round()函数的PHP_ROUND_AWAY_FROM_ZERO模式保持一致。 -
NumberFormatter::ROUND_HALFODD(值为 int(8)):用于补充NumberFormatter::ROUND_HALFEVEN功能,但这个常量在 PHP 8.4 之前并未声明。
向后兼容性影响
PHP_ROUND_CEILING、PHP_ROUND_FLOOR、PHP_ROUND_TOWARD_ZERO 和 PHP_ROUND_AWAY_FROM_ZERO 是在 PHP 8.4 中声明的新常量。
Intl 扩展中的 NumberFormatter 类增加了 NumberFormatter::ROUND_TOWARD_ZERO 作为 NumberFormatter::ROUND_DOWN 的别名,以及 NumberFormatter::ROUND_AWAY_FROM_ZERO 作为 NumberFormatter::ROUND_UP 的别名。
此外,NumberFormatter 类还声明了一个新的 NumberFormatter::ROUND_HALFODD 常量,该常量提供了与 round() 函数使用 PHP_ROUND_HALF_ODD 模式时相同的功能。这个常量在 PHP 8.4 之前并未声明,尽管 NumberFormatter::ROUND_HALFEVEN 已经存在。