我正在寻找在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)
答案 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
但有两点需要注意:
许多编译器/口译员会自动为您执行此操作,因此无需再次猜测;
除非您在单脚本执行此任务至少100,000次,否则请不要理会。这是一个毫无意义的微观优化。
要进一步详细说明(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)
我通常使用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()