4、PHP 8.4 新特性 - BCMath 扩展新增 bcdivmod 函数

作者: 温新

图书: 【PHP 8.4 新特性】

阅读: 124

时间: 2025-01-17 10:56:27

在 PHP 8.4 中,BCMath 扩展引入了一个新的函数:bcdivmod。这个函数可以同时计算两个大数的商和余数,它是 bcdiv()bcmod() 函数的组合,从而简化了在执行除法运算时同时获得商和余数的操作。

返回值是一个数组,第一个值是商,第二个值是余数。

函数签名

/**
 * @param string $num1 被除数,以字符串形式表示。
 * @param string $num2 除数,以字符串形式表示。
 * @param int|null $scale 余数中小数点后的位数。如果省略或为 null,则默认使用通过 bcscale() 函数全局设置的精度,
 *  或者如果没有设置,则使用 bcmath.scale INI 配置项的值(默认为 0)。
 *
 * @return array 返回一个数组。
 */
function bcdivmod(string $num1, string $num2, ?int $scale = null): array {}
  • bcdivmod 在全局命名空间中声明。
  • 如果 scale 值为 null,则它将继承使用 bcscale 函数设置的 scale 值,并回退到 bcmath.scale INI 值。
  • 返回值始终是一个数组。
  • $num 2 参数传递 0 将引发 DivisionByZeroError 异常。
  • $num 1$num 2 参数传递非数字字符串会引发 ValueError 异常,指出该值格式不正确。

为什么需要 bcdivmod

在进行大数除法时,通常我们会分别调用 bcdiv() 来获取商,和 bcmod() 来获取余数。这样会增加额外的计算开销,并且需要两次函数调用。而 bcdivmod() 函数将这两者结合起来,一次性返回商和余数,从而优化了性能。

用法对比

bcdiv()bcmod() 的用法:

<?php
    
$num1 = "1000";
$num2 = "300";

$quotient = bcdiv($num1, $num2);  // 商
$remainder = bcmod($num1, $num2); // 余数
echo "商: $quotient, 余数: $remainder";  // 商: 3, 余数: 100

使用 bcdivmod() 则可以简化为:

<?php
    
$num1 = "1000";
$num2 = "300";

$result = bcdivmod($num1, $num2);  // 返回商和余数
echo "商: " . $result[0] . ", 余数: " . $result[1];  // 商: 3, 余数: 100

bcdivmod 用法

案例一:基本用法

<?php
    
declare(strict_types=1);

$num1 = '1000';
$num2 = '300';
$result = bcdivmod($num1, $num2);
print_r($result);

输出

Array
(
    [0] => 3	// 商
    [1] => 100	// 余数
)

案例二:指定小数精度

<?php

declare(strict_types=1);

$num1 = '1000';
$num2 = '300';
$result = bcdivmod($num1, $num2, 2);
print_r($result);

输出

Array
(
    [0] => 3
    [1] => 100.00
)

案例三:零除错误

<?php

declare(strict_types=1);

$num1 = "1000";
$num2 = "0";
$result = bcdivmod($num1, $num2);

输出

PHP Fatal error:  Uncaught DivisionByZeroError: Division by zero in 

案例四:值错误

<?php

declare(strict_types=1);

$num1 = "1000";
$num2 = "aa";
$result = bcdivmod($num1, $num2);

输出

PHP Fatal error:  Uncaught ValueError: bcdivmod(): Argument #2 ($num2) is not well-formed in 

bcdivmod 优势

  • 性能优化:相比分别调用 bcdiv()bcmod()bcdivmod() 通过一次调用同时返回商和余数,减少了计算开销,提升了性能,尤其是在大量大数运算时。
  • 代码简洁bcdivmod() 使得代码更简洁,不需要手动处理商和余数的分离。
  • 更高效的处理大数运算BCMath 扩展专为大数运算设计,bcdivmod() 在处理非常大的整数或浮点数时提供了更高效和准确的结果。

bcdivmod 错误条件

bcdivmod 函数遵循与 BCMath 扩展中的其他函数类似的语义。传递非数字值会引发 ValueError 异常,并且由于 $num 1$num 2 参数的类型声明是字符串,因此当 declare(strict_types=1) 生效时,它遵循标准的 PHP 类型强制和严格类型规则。

向后兼容性影响

bcdivmod] 是 PHP 8.4 BCMath 扩展中新增的函数。除非存在同名的现有全局函数,否则此更改不会导致任何向后兼容性问题。

请登录后再评论