php tamsayı bölme

6 Cevap php

Ben php bir tamsayı bölme yapmak için en hızlı yol arıyorum. örneğin, 5/2 2 olması schould ve 6/2 kadar 3 olması ve olmalıdır. ben sadece bunu eğer, php ilk durumda 2.5 dönecektir, bulabildiğim tek çözüm kullanan intval($my_number/2) - wich kadar hızlı i olmak istiyorum olarak değil (ancak beklenen sonuç verir) .

Herkes bu konuda bana yardımcı olabilir?

EDIT:
thanks to all of you for your ideas, i used the script postet 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 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

Bugüne kadar, bit-shift hızlı yoludur, ama bu diğer possibilitys olup olmadığını görmek için bir gün boyunca açık bu soruyu bırakacağım ...

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

6 Cevap

2 tarafından bölünme ise, bunu yapmak için en hızlı yolu biraz kayması olduğunu.

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 

Sadece bir int döküm:

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

Sebebi ne olursa olsun, bu intval() çok daha hızlıdır.

Edit: I assume bir general tamsayı bölme çözüm arıyoruz. Bit değişen 2 yetkileri (veya çarparak) bölünmesi için özel bir durum o zaman sizi ilgilendiriyorsa.:

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

bu yüzden:

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

Ama iki uyarılar:

  1. İkinci bunu tahmin anlamı yok bu yüzden pek çok derleyiciler / tercümanlar sizin için otomatik olarak yapacak;

  2. Eğer bu bölünme yapıyoruz sürece bir single komut dosyası yürütme, en az 100,000 kere zahmet etmeyin. Bu anlamsız bir mikro-optimizasyon bulunuyor.

Ayrıca (2), evet (int) parseInt() daha hızlıdır ama fark eder üzerinde durmak? Neredeyse kesinlikle değil. Okunabilir kod ve iyi bir algoritma odaklanın. Bu tür bir şey alakasız bir oyalama.

Sadece test:

Sonuç (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

Kod:

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

Selamlar

rbo

Heh, ben 2010 den görünüyor ve bu gerçekten bir cevap değil gibi ben bu soruya nasıl girdiğini bilmiyorum, ama yazar inegers bölmek için tüm yolları toplamak gibi görünüyor hızlı burada birisi yardımcı olabilir.

Ben kendim için hızlı kod yazmak çünkü ne zaman, yerine (int) ve "| |" operatörü en sonra diğer operatörleri sevgilisi önceliğe sahip ekstra parantez gerek kalmaz, ben genelde 0 kullanın. Hatta

$x=0| 0.3+0.7;

özel operatör "olarak ayarlayın ve int dökme" olarak | "= 0" beklenen ve ben sadece düşünüyorum olarak (en azından benim için) koduna baktığınızda kolayca bulunur olarak çalışacaktır.

Yani, (bu sadece int için döküm sadece başka yolları da vardır) koleksiyonuna eklemek için:

$c=0| $x/$y;

ve

$c=$x/$y % PHP_INT_MAX;

$ X ve $ y tamsayı ise yalnızca çalışır

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

() veya hücrelerinin, () veya zemin yuvarlak kullanın () işlevleri aksi int gibi önce türü bildirmek ()