PHP中计算模数($a除以$b的余数)的最佳函数或方法是什么


What is the best function or method for computing modulus (Remainder of $a divided by $b) in PHP?

PHP为计算模数提供了不同的功能:

  1. 模算子%:echo ($a % $b);
  2. fmod()
  3. bcmod()
  4. gmp_mod()

应该使用哪种被认为安全有效的功能?考虑这里描述的(零除法问题:使用模数和浮点数时的零除法误差?

  1. 只有模运算符(%)和fmod是本机

  2. 模数运算符不能处理超过2^32的数字(在运行x86体系结构的PHP上)

  3. fmod运行速度快于bcmod/gmp_mod ~基准

  4. bcmod不适用于浮动~这里是

我认为最好使用fmod,因为它在数学函数中,运行速度比其他函数快得多,而且最重要的是,它可以处理大数字和浮点值。

如果您不打算使用超过限制或浮动的数字,请使用%,因为它应该是最快的。

只要知道在做什么,所有函数都可以安全使用:

  1. 模运算符:速度快,精度高,但需要保持在最大整数以下。在这个术语中不存在被零除的问题。

  2. fmod:仍然很快,浮点运算速度在过去10年里不再是一个问题,而是一个棘手的问题。浮点数字可以达到更高的值,但它们的精度不能。因此,使用大数字将越来越多地引入舍入误差。因此不会解决模算子所缺乏的任何问题,反而会引入精度问题。

  3. bcmod和gmp_mod是simmilar。不同之处在于,这些函数使用了任意精度算术的不同实现(模块)。它们的用法不同,但结果不同:理论上,这些库支持的数字的大小仅受可用内存量的限制,因此实际上结果总是好的和精确的,然而,从计算和内存的角度来看,使用的算法都是过度的。

您仍然可以使用模运算符,并且如果您计划在某个点期望为零,它仍然是安全的,如下所示。

if ($y > 0) {
  // Do the calculation
}
else {
  // Do this instead
}

为了隐藏警告,还可以使用错误控制运算符。通过使用@运算符,可以抑制错误。

然而,对于%,整数在转换为浮点值之前只能变大,因此引入了bcmod和fmod,但请注意,它们都有自己的局限性。

我推荐GMP,或者看看其他增强的数学函数之一,还有BCMath

既然你提到了一些安全的东西,就有一个类:Eval数学

下面是一个使用fmod 的示例

<?php
echo fmod('4294967296', 34);
?>

输出18

注意,fmod并不等同于这个基本函数:

    <?php 
    function modulo($a, $b) { 
    return $a - $b * floor($a / $b); 
    } 
    ?> 

因为fmod()将返回一个与$a符号相同的值。换句话说,floor()函数是不正确的,因为它向-INF而不是向零取整。

要模拟fmod($a,$b),正确的方法是:

    <?php 
    function fmod($a, $b) { 
    return $a - $b * (($b < 0) ? ceil($a / $b) : floor($a / $b))); 
    } 
    ?> 

注意,如果$b为null,两个函数都将抛出一个DIVISION BY ZERO。

上面的第一个函数modulo()是一个数学函数,它适用于处理循环结构(如日历计算或三元非度量函数:

    - fmod($a, 2*PI) returns a value in [0..2*PI) if $a is positive 
    - fmod($a, 2*PI) returns a value in [-2*PI..0] if $a is negative 
    - modulo($a, 2*PI) returns a value always in [0..2*PI) independantly of the sign of $a