代码之家  ›  专栏  ›  技术社区  ›  oezi

PHP中的整数除法

  •  23
  • oezi  · 技术社区  · 15 年前

    我正在寻找用PHP进行整数除法的最快方法。例如,5/2应该是2,6/2应该是3,依此类推。如果我这么做,在第一种情况下,PHP将返回2.5,我能找到的唯一解决方案是使用 intval($my_number/2) -威奇没有我想要的那么快(但给出了预期的结果)。

    有人能帮我吗?

    编辑:
    感谢大家的想法,我使用了Rubber_Boots的脚本Postet,用10000000次迭代来测试其中的一些,在这里您可以看到结果(Mamp在3或4岁的MacBook上使用2GHz Intel Core 2 Duo):

    start (10000000)
    (int)...: 2.26 sec
    floor(): 4.36 sec
    int_divide(): 2.86 sec
    bit-shift: 1.45 sec //note: only works for divisions through powers of 2
    intval(): 4.51 sec
    round() with PHP_ROUND_HALF_DOWN: 5.48 sec
    

    到目前为止,比特移位是最快的方法,但我会让这个问题开放一天,看看是否还有其他的可能性…

    编辑2:
    更新了结果,用php-round-half-down添加了round()(多亏了col.\u弹片)

    7 回复  |  直到 13 年前
        1
  •  28
  •   Alex    15 年前

    如果除以2,最快的方法就是移位。

    5>>1 = 2
    6>>1 = 3
    

    等等。 它所做的只是将位右移1位,从而将数字除以2,剩下的就丢失了。

    1110 >> 1 =  111
    1011 >> 1 =  101
    1011 >> 2 =   10 //division by 4
    1011 << 1 =10110 
    
        2
  •  33
  •   cletus    15 年前

    把它转换成int:

    $result = (int)(6 / 2);
    

    不管什么原因,它比 intval() .

    编辑: 假定 你在找一个 一般的 整数除法。比特移位是一种特殊情况,用2的幂除(或乘)2。如果你对此感兴趣,那么:

    a / b^n = a >> n where a, b, n are integers
    

    所以:

    a / 2 = a / 2^1 = a >> 1
    

    但有两个警告:

    1. 许多编译器/解释器会自动为您完成这项工作,因此没有必要再进行猜测;

    2. 除非你在一个 单一的 脚本执行不麻烦。这是一个毫无意义的微观优化。

    进一步阐述(2),是的 (int) 比…快 parseInt() 但这有关系吗?几乎肯定不会。专注于可读代码和良好的算法。这类事情是不相干的干扰。

        3
  •  5
  •   XzKto    13 年前

    呵呵,我不知道我是怎么进入这个问题的,因为这个问题似乎是从2010年开始的,这并不是一个真正的答案,但是作者似乎收集了所有的方法来快速划分贫富差距,这可能对这里的人有所帮助。

    当我为自己编写快速代码时,我通常使用0而不是(int),因为“”运算符的优先级高于大多数其他运算符,所以您不需要额外的括号。偶数

    $x=0| 0.3+0.7;
    

    将按预期工作,当您查看代码(至少对我而言)时,很容易找到它,正如我所认为的“=0”作为特殊运算符“set and cast to int”。

    因此,要添加到集合中(这些只是转换为int的其他方法):

    $c=0| $x/$y;
    

    $c=$x/$y % PHP_INT_MAX;
    
        4
  •  4
  •   rubber boots    15 年前

    只是测试一下:

    结果(win32,core2/e6600):

     generic division (3000000)
     (int)DIV:       1.74 sec
     intval(DIV):    6.90 sec
     floor(DIV):     6.92 sec
     int_divide():   1.85 sec
    
     division by 2 (3000000)
     (int)(VAL/2):   1.75 sec
     VAL >> 2:       1.63 sec
     (int)(VAL*0.5): 1.72 sec
    

    代码:

     ...
     echo "generic division ($N)\n";
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = (int)(($i+1) / $i); }
     printf("(int)DIV:\t %.2f sec\n", getTime()-$start);
    
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = intval(($i+1) / $i); }
     printf("intval(DIV):\t %.2f sec\n", getTime()-$start);
    
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = floor(($i+1) / $i); }
     printf("floor(DIV):\t %.2f sec\n", getTime()-$start);
    
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = ($i - ($i % ($i+1))) / ($i+1); }
     printf("int_divide():\t %.2f sec\n", getTime()-$start);
    
     echo "division by 2 ($N)\n";
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = (int)(($i+1) / 2.0); }
     printf("(int)(VAL/2):\t %.2f sec\n", getTime()-$start);
    
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = ($i+1) >> 2; }
     printf("VAL >> 2:\t %.2f sec\n", getTime()-$start);
    
     $start = getTime(); for($i=1; $i<$N; $i++) { $c = (int)(($i+1)*0.5); }
     printf("(int)(VAL*0.5):\t %.2f sec\n", getTime()-$start);
     ...
    

    当做

    RBO

        5
  •  2
  •   ghoppe    15 年前

    只有当$x和$y是整数时才有效

    function int_divide($x, $y) {
        return ($x - ($x % $y)) / $y;
    }
    
        6
  •  1
  •   Your Common Sense    15 年前

    圆形()通常用于这种目的。但我不知道它的速度。 我的代码中从来没有进行过数百万次计算。最多只有十分之几。

        7
  •  1
  •   Karthik    15 年前

    使用round()或ceil()或floor()函数,否则在like int()之前声明类型