Изменения

Перейти к: навигация, поиск

Побитовые операции

571 байт добавлено, 21:50, 6 марта 2016
Побитовые сдвиги
Операторы сдвига <tex>\ll</tex> и <tex>\gg</tex> сдвигают биты в переменной влево или вправо на указанное число. Сдвиг влево может применяться для умножения числа на два, сдвиг вправо — для деления.
<code>
x = 7; <font color = green>//00000111</font>  x << 1; <font color = green>//00001110</font>  x << 5; <font color = green>//11000000</font>  x >> 2; <font color = green>//00110000</font>
</code>
====Ограничения====
'''''C++ Visual Studio 15'''''
 
Если выполняется сдвиг влево числа со знаком и при этом затрагивается бит знака, результат не определен. Результат сдвига вправо отрицательного числа со знаком зависит от реализации. Результат операции сдвига не определен, если число, на которое пользователь хочет сдвинуть биты имеет отрицательное значение или если оно больше или равно количеству битов в исходном числе.
<code>
#include <iostream>#include <bitset>using namespace std; int main() { '''short short1 ''' x = 16384; bitset<16font color = green> bitset1{short2}; cout << bitset1 << endl; // 0100000000000000 01000000 00000000<br/font> '''short short3 ''' y = short1 x << 1; bitset <16font color = green> bitset3{short3}; // 16384 left-shifted by 1 = -32768 cout 10000000 00000000<< bitset3 << endl; // 100000000000000 <br/font> short short4 <font color = short1 << 14; bitset<16green> bitset4{short4}; // 4 16384 left-shifted by 14 1 = 0 cout << bitset4 <-32768< endl; // 000000000000000 }font>
</code>
'''''Java'''''
 В языке программирования Java существует также оператор беззнакового битового сдвига вправо <tex>>>>\ggg</tex>. При использовании этого оператора на освободившиеся позиции всегда устанавливаются <tex>0</tex>, тогда как при использовании <tex>>>\gg</tex> на освободившиеся позиции устанавливается бит знака.
При использовании битовых сдвигов есть некоторое отличие от целочисленного деления на <tex>2</tex>: если сдвигать отрицательное число вправо, то сначала это аналогично целочисленному делению на <tex>2</tex>, но когда останется <tex>-1</tex>, то при следующих сдвигах результат меняться не будет. То есть происходит округление не к нулю, как при целочисленном делении, а к <tex>-1</tex>.
Нельзя Также нельзя сдвинуть число на количество бит большее, чем разрядность операнда. При этом происходит неявное сокращение правого (кол-во количество бит) операнда.
''Примеры:''<code> i = 1 <font color = green>//00000000 00000000 00000000 00000001 (1)</font> i << 29 <font color = green>//00100000 00000000 00000000 00000000 (536870912)</font> i << 30 <font color = green>//01000000 00000000 00000000 00000000 (1073741824)</font> i << 31 <font color = green>//10000000 00000000 00000000 00000000 (-2147483648 / 2147483648)</font> i << 32 <font color = green>//00000000 00000000 00000000 00000001 (1)</font></code>
<code>
i 00000000000000000000000000000001 = -1 <font color = green>//11111111 11111111 11111111 11111111 (-1/ 4294967295) <br/font> i>>> 1 <<29 00100000000000000000000000000000 font color = green>//01111111 11111111 11111111 11111111 (5368709122147483647) <br/font> i>>> 30 <<30 01000000000000000000000000000000 font color = green>//00000000 00000000 00000000 00000011 (10737418243) <br/font> i>>> 31 <<31 10000000000000000000000000000000 font color = green>//00000000 00000000 00000000 00000001 (-2147483648/21474836481) <br/font> i>>> 32 <<32 00000000000000000000000000000001 font color = green>//11111111 11111111 11111111 11111111 (-1/ 4294967295)</font>
</code>
 
<code>
i 11111111111111111111111111111111 = -192 <font color = green>//11111111 11111111 11111111 01000000 (-1192 /42949672954294967104) <br/font> i>>1 <font color = green>1 01111111111111111111111111111111 //11111111 11111111 11111111 10100000 (2147483647-96 / 4294967200) <br/font> i>>30 <font color = green>30 00000000000000000000000000000011 //11111111 11111111 11111111 11111111 (3-1 / 4294967295) <br/font> i>>31 <font color = green>31 00000000000000000000000000000001 //11111111 11111111 11111111 11111111 (-1/ 4294967295) <br/font> i>>32 <font color = green>32 11111111111111111111111111111111 //11111111 11111111 11111111 01000000 (-1192 /42949672954294967104)</font>
</code>
 
Арифметическое распространение в Java проводится перед операциями и гарантирует расширение каждого операнда по крайней мере до int (или, если один из операндов имеет больший тип, то до него). Расширение происходит знаково, ввиду чего результат может быть не таким, как ожидалось; при приведении типа к меньшему лишние байты отбрасываются.
 
''Примеры:''
<code>
i 11111111111111111111111101000000 '''byte''' b = -127 <font color = green>//10000001 (-192127 /4294967104129) <br/font>i>>1 11111111111111111111111110100000 (-96/4294967200'''int''') b <brfont color = green>/>i>>30 11111111111111111111111111111111 /11111111 11111111 11111111 10000001 (-1127 /42949672954294967169) <br/font '''int''' i= -127 <font color = green>>31 11111111111111111111111111111111 //11111111 11111111 11111111 10000001 (-1127 /42949672954294967169) <br/font> ('''byte''')i <font color = green>>32 11111111111111111111111101000000 //10000001 (-192127 /4294967104129)</codefont>
Арифметическое распространение в Java проводится перед операциями и гарантирует расширение каждого операнда по крайней мере до '''int. Если же один из операндов long, то до long. Если сдвигаемая переменная по разрядности меньше, то результат будет не таким, как ожидалось. При приведении типов при расширении разрядности расширение происходит знаково. При сжатии разрядности просто отбрасываются лишние байты.''' i = 128 <font color = green>//00000000 00000000 00000000 10000000 (128)</font> ('''byte''')i <font color = green>//10000000 (-128 / 128)</font>
Примеры: '''int''' i = 256 <font color = green>//00000000 00000000 00000001 00000000 (256)</font> ('''byte''')i <font color = green>//00000000 (0)</font>
<code>byte b = -127; <br/>b 10000001 (-127/129) <br/>(int)b 11111111 11111111 11111111 10000001 (-127/4294967169) <br/>'''int ''' i = -127; 256 <brfont color = green>//>i 11111111 11111111 11111111 10000001 (-127/4294967169) <br/>(byte)i 10000001 (-127/129) <br/>int i = 128; <br/>i 00000000 00000000 00000000 10000000 (128) <br/>(byte)i 10000000 (-128/128) <br/>int i = 256; <br/>i 00000000 00000000 00000001 00000000 (2564294967040) <br/font> ('''byte''')i 00000000 (0) <br/>int i font color = -256; <br/green>i 11111111 11111111 11111111 00000000 (-256/4294967040) <br/>(byte)i 00000000 (0) <br/font>
</code>
276
правок

Навигация