Что значит> и значит 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 и int
ing результат.
вот хорошая ссылка для операторов и их приоритета: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
.