Что значит> и значит 0xfffffff8?

мне сказали, что (i >> 3) is faster than (i/8) но я не могу найти никакой информации о том, что >> есть. Может кто-нибудь указать мне на ссылку, которая все объясняет?

тот же человек сказал мне:"int k = i/8, следовал по k*8 лучше выполняется (i&0xfffffff8); " но опять же Google не помог м...

Спасибо за любые ссылки!

11 ответов


как пояснил здесь на >> оператор - это просто побитовое смещение битов i. Такая переменчивая i 1 бит вправо приводит к целочисленному делению на 2, а сдвиг на 3 бита приводит к делению на 2^3=8.

но в настоящее время эта оптимизация для деления на две степени больше не должна выполняться, так как компиляторы должны быть достаточно умными, чтобы сделать это сами.

аналогично побитовым и с 0xFFFFFFF8 (1...1000, последние 3 bits 0) равно округлению i до ближайшего кратного 8 (например,(i/8)*8 делает), так как он будет обнулять последние 3 бита i.


побитовый сдвиг вправо. i >> 3 перемещение i целое число 3 места справа [двоичный путь] - ака, разделить на 2^3.


int x = i / 8 * 8:

1) i / 8, можно заменить на i >> 3-побитовый сдвиг вправо на 3 цифры (8 = 2^3)

2) сравнение i & xfffffff8 с маской Например у вас есть:

i = 11111111
k (i/8) would be: 00011111  
x (k * 8) would be: 11111000

поэтому операция просто сбрасывает последние 3 бита: И сопоставимые затраты времени операции умножения и деления могут быть переписаны просто с

i & xfffffff8-сравнение с (... 11111000 маски)



на >> оператор-оператор сдвига битов. Он берет бит, представленный значением, и сдвигает их на заданное количество слотов вправо.


Что касается первого тайма:

>> немного мудрый сдвиг вправо.

таким образом, смещение числового значения 3 бита вправо-это то же самое, что деление на 8 и inting результат.

вот хорошая ссылка для операторов и их приоритета:http://web.cs.mun.ca / ~michael/c/op.html

вторая часть вашего вопроса включает в себя & оператор, который немного мудр и. Пример-ANDing i и a число, которое оставляет все биты, за исключением 3 наименее значимых. То же самое происходит, когда у вас есть число, разделите его на 8, сохраните результат как целое число, а затем умножьте этот результат на 8.

причина этого в том, что деление на 8 и сохранение в виде целого числа совпадает с битовым сдвигом вправо на 3 места, а умножение на 8 и сохранение результата в int совпадает с битовым сдвигом влево на 3 места.

Итак, если ты умножение или деление на степень 2, например 8, и вы примете усечение битов, которое происходит, когда вы сохраняете этот результат в int, бит-сдвиг быстрее, оперативно. Это потому, что процессор может пропустить алгоритм умножения / деления и просто перейти прямо к сдвигу битов, что включает в себя несколько шагов.


побитовый сдвиг.

Предположим, у меня есть 8-битное целое число, в двоичном

01000000

если я оставил shift (>>оператор) 1 результат

00100000

если я тогда правый сдвиг (

01000000

оказывается, потому что первое двоичное целое число равно

0*2^7 + 1*2^6 + 0*2^5 + 0*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 0*2^0

или просто 2^6 или 64

когда мы вправо shift 1 мы получаем следующее

0*2^7 + 0*2^6 + 1*2^5 + 0*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 0*2^0

или просто 2^5 или 32

что означает

i >> 1 

это то же самое, что

i / 2

если мы сдвинемся еще раз (i >> 2), мы эффектно разделяем 2 еще раз и get

i / 2 / 2

что на самом деле

i / 4

не совсем математическое доказательство, но вы можете увидеть следующий верна

i >> n == i / (2^n)

это называется битовым сдвигом, это операция над битами, например, если у вас есть число на двоичной базе, скажем, 8, это будет 1000, так что

x = 1000;
y = x >> 1; //y = 100 = 4
z = x >> 3; //z = 1 

ваш сдвиг битов в двоичном формате, например:

1000 == 8

0100 == 4 (>> 1)

0010 == 2 (>> 2)

0001 == 1 (>> 3)

поскольку вы используете систему base two, вы можете воспользоваться определенными делителями (только целыми числами!) и просто бит-шифт. Кроме того, я считаю, что большинство компиляторов знают это и сделают это для вас.

Что касается второго часть:

(i&0xfffffff8);

скажи i = 16

0x00000010 & 0xfffffff8 == 16

(16 / 8) * 8 == 16

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


>> is право операции сдвига.

Если у вас есть число 8, которое представлено в двоичном виде как 00001000, смещение битов вправо на 3 позиции даст вам 00000001, который является десятичным 1. Это эквивалентно делению на 2 три раза.

деление и умножение на одно и то же число означает, что вы устанавливаете некоторые биты справа на ноль. То же самое можно сделать, если применить маску. Скажем, 0xF8 является 11111000 побитовым, и если вы и это число, он установит свои последние три бита на ноль, а другие биты будут оставлены как есть. Например, 10 & 0xF8 будет 00001010 & 11111000, что равно 00001000, или 8 в десятичной дроби.

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


>> сдвигает число вправо. Рассмотрим двоичное число 0001000, который представляет 8 в десятичной системе счисления. Смещение его на 3 бита вправо дало бы 0000001 номер 1 в десятичной системе счисления. Таким образом, вы видите, что каждый 1-битный сдвиг вправо на самом деле является делением на 2. Обратите внимание, что оператор усекает плавающую часть результата. Поэтому i >> n подразумевает i/2^n. Это может быть быстро, в зависимости от реализации компилятора. Но это обычно занимает поместите прямо в регистры и поэтому очень быстро по сравнению с традиционным делением и умножением.

ответ на вторую часть содержится в самой первой. Поскольку деление также усекает всю плавающую часть результата, деление на 8 теоретически будет смещать ваш номер 3 биты вправо, тем самым теряя всю информацию о самых правых 3 битах. Теперь, когда вы снова умножите его на 8 (что теоретически означает смещение влево на 3 бита), вы не приукрашиваете righmost 3 бита на ноль после сдвига результата влево на 3 бита. Таким образом, полная операция может рассматриваться как одна операция "&" с 0xfffffff8 что означает, что число имеет все биты 1, кроме самого правого 4 битов,1000.