php中的整数除法

时间:2010-04-20 08:58:11

标签: php performance math

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

任何人都可以帮我解决这个问题吗?

修改
感谢大家的想法,我使用rubber_boots的脚本postet测试其中一些10000000次迭代,在这里你可以看到结果(3或4岁的MacBook上有2Ghz intel core 2 duo的MAMP):< / p>

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

直到现在,位移是最快的方式,但是我会把这个问题留一天,看看是否有其他可能性...

EDIT2:
更新了结果,使用PHP_ROUND_HALF_DOWN添加了round()(感谢Col._Shrapnel)

7 个答案:

答案 0 :(得分:33)

将它转换为int:

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

无论出于何种原因,它都比intval()快得多。

编辑:假设您正在寻找一般整数除法解决方案。位移是一种特殊情况,用于除以(或乘以)2的幂。如果你感兴趣那么:

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

这样:

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

但有两点需要注意:

  1. 许多编译器/口译员会自动为您执行此操作,因此无需再次猜测;

  2. 除非您在脚本执行此任务至少100,000次,否则请不要理会。这是一个毫无意义的微观优化。

  3. 要进一步详细说明(2),是(int)parseInt()快,但重要吗?几乎肯定不是。专注于可读代码和良好的算法。这种事情是无关紧要的分心。

答案 1 :(得分:28)

如果除以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 :(得分:5)

嘿,我不知道我是怎么进入这个问题的,因为它似乎是从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;

答案 3 :(得分:4)

试试吧:

结果(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

答案 4 :(得分:2)

仅当$ x和$ y为整数

时才有效
function int_divide($x, $y) {
    return ($x - ($x % $y)) / $y;
}

答案 5 :(得分:1)

圆形()通常用于此目的。但我不知道它的速度。 我的代码中从未有过数百万次计算。仅仅十分之几。

答案 6 :(得分:1)

使用round()或ceil()或floor()函数否则声明类型,如int()

相关问题