2012-02-15 19 views
2

Мне дано большое целое число a и (относительно небольшое) целое число n.Получить точность n-го бита целого

Что является самым быстрым способом получить n-й бит (справа) от двоичного разложения a с использованием Python? (Я не хочу, чтобы написать C pluggin, просто Python.)

+0

Какой размер большой? –

+0

@JohnMachin: 'a' имеет около 1000 цифр,' n' составляет около 1000. – Randomblue

ответ

6

Вы просили за быстрый образом, по-видимому, используя современную версию Python. Современные версии Python имеют переменную длину ints, и обычная мудрость не применяется. Смещение большого числа не из дешевых. Смещение 1 дешево. Вот некоторые входы -mtimeit и соответствующие выходы. Первая аббревиатура

windows command prompt>\python27\python -mtimeit -s"a=10**20;n=3" "(a>>n)&1" 
1000000 loops, best of 3: 0.238 usec per loop 

-s"a=10**20;n=3" "(a>>n)&1" 
0.238 usec 

-s"a=10**20;n=3" "not not(a & (1 << n))" 
0.154 usec 

-s"a=10**200;n=3" "(a>>n)&1" 
0.382 usec 

-s"a=10**200;n=3" "not not(a & (1 << n))" 
0.155 usec 

-s"a=10**10;n=3" "(a>>n)&1" 
0.231 usec 

-s"a=10**10;n=3" "not not(a & (1 << n))" 
0.156 usec 

-s"a=10**9;n=3" "(a>>n)&1" 
0.0801 usec 

-s"a=10**9;n=3" "not not(a & (1 << n))" 
0.0938 usec 

-s"a=2**1000;n=64" "(a>>n)&1" 
0.446 usec 

-s"a=2**1000;n=64" "not not(a & (1 << n))" 
0.255 usec 

Если not not(foo) уроды вас, или вы действительно хотите, int ответ вместо bool, вы можете использовать 1 if foo else 0; он только немного медленнее.

+0

Хорошее наблюдение. Только для записи в Python 3.1 с различием между 'long' и' int', прямой подход также является самым быстрым (по крайней мере, на моей машине). –

+0

@SvenMarnach: Я получаю аналогичные результаты с 2,7, 3,1 и 3,2 ... Сегодня я сделаю более полную оценку; должен уйти сейчас ... –

+0

Полные [тайминги на моей машине] (https://gist.github.com/1839351) действительно более дифференцированы, чем предлагает мой предыдущий комментарий. (Раньше я делал только некоторые из ваших тестов и попадал в те, где прямолинейный подход быстрее). –

7

Сдвинуть битную последней позиции, маскировать Everthing еще:

bit = (a >> n) & 1 

Это предполагает, что биты нумеруются в обычном путь, т.е. наименьший значащий бит является бит 0.

Edit: Я не уверен, если это быстрый способ сделать это в вашей версии Python, но, по крайней мере, это самый прямой вперед. В зависимости от вашей версии Python и конкретных значений a и n могут быть более быстрые способы, как показано в answer by John Machin.

+0

-1 Что создает впечатление, что это самый быстрый способ, под каким определением «большой» и «относительно небольшой»? –

+1

@JohnMachin: Я мог видеть из этого вопроса и из других вопросов OP, что пользователь вообще не знал *, как это сделать. Моя интерпретация вопроса заключается в том, что «самый быстрый» мог быть «самым легким» или «лучшим» или что-то еще. В таком случае я стараюсь быть полезным и объяснять самые основы. Если вы действительно думаете, что этот ответ * не * полезен, тогда я должен согласиться с тем, что ваше понимание полезности сильно отличается от моего. (Я думаю, что ваш ответ и ваш способ прочитать вопрос совершенно верны.) –

+1

Я не могу удалить голосование, пока вы не отредактируете свой ответ (возможно, объясните свое определение «самый быстрый»). –

-1

Использование п, начиная с 0:

(a >> n) & 1 
+0

Этот ответ был дан на 1 минуту позже, чем эквивалентный и более подробный из них @SvenMarnach. Я предлагаю удалить его. – texnic

Смежные вопросы