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
已经存在。