7

PHP 提供了不同的计算模数的函数:

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

应该使用哪个功能被认为是安全有效的?考虑到此处描述的(除零问题:使用模数和浮点数时除以零错误?

4

4 回答 4

21
  1. 只有模数运算符 (%) 和 fmod 是原生的

  2. 模数运算符无法处理超出的数字2^32(在运行 x86 架构的 PHP 上)

  3. fmod 运行速度比 bcmod/gmp_mod 快~ benchmark

  4. bcmod 不适用于浮点数 ~这里

我相信最好使用fmod,因为它在Math Functions中,运行速度比其他函数快,最重要的是,可以处理大数字和浮点数。

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

于 2013-08-06T01:18:50.167 回答
2

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

  1. 模数运算符:快速、精确,但您需要保持在最大 int 之下。在这个条款中,没有任何除以零的问题。

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

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

于 2013-08-14T20:03:40.833 回答
1

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

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

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

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

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

既然你提到了一些安全的东西,那么有一个课程: Eval Math

这是一个使用示例fmod

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

输出18

于 2013-08-08T15:08:51.650 回答
0

请注意, 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 为空,这两个函数都将抛出除零。

上面的第一个函数 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
于 2013-08-13T06:30:38.287 回答