开发者

integer division in php

开发者 https://www.devze.com 2022-12-27 06:17 出处:网络
I\'m looking for the fastest way to do an integer division in php. for example, 5 / 2 should be 2 and 6 / 2 should be 3 and so on. If I simply do this, php will return 2.5 in the first case, the only

I'm looking for the fastest way to do an integer division in php. for example, 5 / 2 should be 2 and 6 / 2 should be 3 and so on. If I simply do this, php will return 2.5 in the first case, the only solution I could find was using intval($my_number/2) - which isn't as fast as I want it to be (but gives the expected results).

How can I do this?

EDIT:

Thanks to all of you for your ideas, I used the script posted by rubber_boots to test some of them with 10000000 iterations, here you can see the results (MAMP on a 3 or 4 year old MacBook with 2Ghz Intel core 2 duo):

start (10000000)
(int)...: 2.26 sec
floor(): 4.36开发者_StackOverflow社区 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

until now, bit-shift is the fastest way, but I'll leave this question open for a day to see if there are other possibilities for this...

EDIT2:

updated the results, added round() with PHP_ROUND_HALF_DOWN (thanks to Col._Shrapnel)


Just cast it to an int:

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

For whatever reason, it's much faster than intval().

Edit: I assume you are looking for a general integer division solution. Bit-shifting is a special case for dividing by (or multiplying by) powers of 2. If that interests you then:

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

so:

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

But two caveats:

  1. Many compilers/interpreters will do this for you automatically so there is no point second guessing it;

  2. Unless you're doing this division at least 100,000 times in a single script execution don't bother. It's a pointless micro-optimization.

To further elaborate on (2), yes (int) is faster than parseInt() but does it matter? Almost certainly not. Focus on readable code and a good algorithm. This sort of thing is an irrelevant distraction.


if it's division by 2, the fastest way to do it is bit shifting.

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

and so on and so forth. What it does is just shift the bits to the right by 1 bit, thus dividing the number by 2 and losing the rest

1110 >> 1 =  111
1011 >> 1 =  101
1011 >> 2 =   10 //division by 4
1011 << 1 =10110 


Heh, I don't know how I got into this question as it seems to be from 2010 and this is not really an answer, but as the author seems to collect all ways to divide inegers fast it may help someone here.

I usually use 0| instead of (int) when I write fast code for myself, because "|" operator have lover precedence then most other operators, so you don't need extra parentheses. Even

$x=0| 0.3+0.7;

will work as expected and it is easily found when you look at code(at least for me) as I just think of "=0|" as special operator "set and cast to int".

So, to add to your collection (these are simply just other ways to cast to int):

$c=0| $x/$y;

and

$c=$x/$y % PHP_INT_MAX;


Just Test it:

Result (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

Code:

 ...
 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);
 ...

Regards

rbo


Only works if $x and $y are integers

function int_divide($x, $y) {
    return ($x - ($x % $y)) / $y;
}


the round() usually used in such a purpose. But I have no idea of it's speed. I have never had millions of calculations in my code. Merely few tenths max.


use round() or ceil() or floor() functions otherwise declare the type before like int()

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号