Подтвердить что ты не робот

Целочисленное деление в php

Я ищу самый быстрый способ сделать целочисленное деление в php. например, 5/2 должно быть 2 и 6/2 должно быть 3 и т.д. если я просто это сделаю, php вернет 2.5 в первом случае, единственным решением, которое я смог найти, было использование intval($my_number/2) - это не так быстро, как я хочу, чтобы он был (но дает ожидаемые результаты).

может кто-нибудь помочь мне с этим?

EDIT:
спасибо всем вам за ваши идеи, я использовал postet от script от rubber_boots для тестирования некоторых из них с итерациями 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

до сих пор, бит-сдвиг является самым быстрым способом, но я оставлю этот вопрос открытым в течение дня, чтобы увидеть, есть ли другие возможности для этого...

EDIT2:
обновил результаты, добавил round() с PHP_ROUND_HALF_DOWN (благодаря Col._Shrapnel)

4b9b3361

Ответ 1

если он делит на 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

Просто добавьте его в 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 раз в одиночном script исполнении, не беспокойтесь. Это бессмысленная микро-оптимизация.

Чтобы подробнее остановиться на (2), да (int) быстрее, чем parseInt(), но имеет ли это значение? Почти наверняка нет. Сосредоточьтесь на читаемом коде и хорошем алгоритме. Такого рода вещи - неважное отвлечение.

Ответ 3

Хе-хе, я не знаю, как я попал в этот вопрос, как кажется, с 2010 года, и на самом деле это не ответ, но поскольку автор, похоже, собирает все способы разделить inegers быстро, он может помочь кому-то здесь.

Я обычно использую 0 | вместо (int), когда я пишу для себя быстрый код, потому что "|" оператор имеет приоритет любовника, а затем большинство других операторов, поэтому вам не нужны дополнительные скобки. Даже

$x=0| 0.3+0.7;

будет работать так, как ожидалось, и его легко найти, когда вы посмотрите на код (по крайней мере, для меня), поскольку я просто думаю о "= 0 |" как специальный оператор "set и cast to int".

Итак, чтобы добавить в вашу коллекцию (это просто другие способы бросить в int):

$c=0| $x/$y;

и

$c=$x/$y % PHP_INT_MAX;

Ответ 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);
 ...

Привет

БВУ

Ответ 5

Работает только в том случае, если $x и $y являются целыми числами

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

Ответ 6

круглый() обычно используется в такой цели. Но я понятия не имею, как быстро. У меня никогда не было миллионов вычислений в моем коде. Всего несколько десятых макс.

Ответ 7

использовать функции round() или ceil() или floor() иначе объявить тип до того, как int()