Arduino:Справочник языка Arduino/Побитовые операторы/Операторы побитового сдвига влево и вправо: различия между версиями

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
м (Замена текста — «<syntaxhighlight lang="c">» на «<syntaxhighlight lang="c" enclose="div">»)
 
Нет описания правки
 
(не показаны 4 промежуточные версии 1 участника)
Строка 1: Строка 1:
{{#setlogo:ArduinoCommunityLogo.png}}
{{Arduino панель перехода}}
{{Arduino панель перехода}}
{{Перевод от Сubewriter}}
{{Перевод от Сubewriter}}
Строка 12: Строка 11:
==Синтаксис==
==Синтаксис==


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
переменная << количество_битов
переменная << количество_битов
переменная >> количество_битов
переменная >> количество_битов
Строка 19: Строка 18:
==Параметры==
==Параметры==


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
переменная (байт, целое, длинное целое), количество_битов (целое <= 32)
переменная (байт, целое, длинное целое), количество_битов (целое <= 32)
</syntaxhighlight>
</syntaxhighlight>
Строка 25: Строка 24:
==Пример==
==Пример==


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
int a = 5;        // в бинарном виде: 0000000000000101
int a = 5;        // в бинарном виде: 0000000000000101
int b = a << 3;  // в бинарном виде: 0000000000101000, или 40 в десятичном
int b = a << 3;  // в бинарном виде: 0000000000101000, или 40 в десятичном
Строка 33: Строка 32:
Когда вы смещаете значение '''X на Y битов влево (X<<Y)''', то левые биты этого значения теряются, а точнее — вовсе перестают существовать.
Когда вы смещаете значение '''X на Y битов влево (X<<Y)''', то левые биты этого значения теряются, а точнее — вовсе перестают существовать.


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
int a = 5;        // в бинарном виде: 0000000000000101
int a = 5;        // в бинарном виде: 0000000000000101
int b = a << 14;  // в бинарном виде: 0100000000000000 – первая единица в «101», по сути, просто исчезает
int b = a << 14;  // в бинарном виде: 0100000000000000 – первая единица в «101», по сути, просто исчезает
Строка 44: Строка 43:
Например, можно задействовать такие выражения:
Например, можно задействовать такие выражения:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
1 <<  0  ==    1
1 <<  0  ==    1
1 <<  1  ==    2
1 <<  1  ==    2
Строка 59: Строка 58:
Когда вы смещаете значение '''X на Y битов вправо (X>>Y)''', и самым первым битом является '''«1»''', то результат зависит от того, какому типу данных соответствует значение '''X'''. Если '''X''' – это целое число, то первый бит будет знаковым битом, который будет определять, будет ли '''X''' значением с отрицательным числом или нет. В этом случае знаковый бит (по никому не ведомым причинам, корни которых затерялись где-то в далеком программистском прошлом) копируется в оставшиеся биты:
Когда вы смещаете значение '''X на Y битов вправо (X>>Y)''', и самым первым битом является '''«1»''', то результат зависит от того, какому типу данных соответствует значение '''X'''. Если '''X''' – это целое число, то первый бит будет знаковым битом, который будет определять, будет ли '''X''' значением с отрицательным числом или нет. В этом случае знаковый бит (по никому не ведомым причинам, корни которых затерялись где-то в далеком программистском прошлом) копируется в оставшиеся биты:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
int x = -16;    // в бинарном виде: 1111111111110000
int x = -16;    // в бинарном виде: 1111111111110000
int y = x >> 3;  // в бинарном виде: 1111111111111110
int y = x >> 3;  // в бинарном виде: 1111111111111110
Строка 66: Строка 65:
Эта особенность, именуемая «знаковым расширением», зачастую бывает вовсе не нужна — например, в случаях, когда вы хотите, чтобы слева появлялись не нули, а единицы. Тут необходимо воспользоваться приведением типов данных и с его помощью сделать X беззнаковым целым числом, поскольку на него это знаковое расширение не действует. В результате слева будут появляться биты, скопированные справа:
Эта особенность, именуемая «знаковым расширением», зачастую бывает вовсе не нужна — например, в случаях, когда вы хотите, чтобы слева появлялись не нули, а единицы. Тут необходимо воспользоваться приведением типов данных и с его помощью сделать X беззнаковым целым числом, поскольку на него это знаковое расширение не действует. В результате слева будут появляться биты, скопированные справа:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
int x = -16;                  // в бинарном виде: 1111111111110000
int x = -16;                  // в бинарном виде: 1111111111110000
int y = (unsigned int)x >> 3;  // в бинарном виде: 0001111111111110
int y = (unsigned int)x >> 3;  // в бинарном виде: 0001111111111110
Строка 73: Строка 72:
Если вам удалось избежать исчезновения нужных битов, то имейте в виду, что оператор «>>» можно использовать еще и как средство для низведения во вторую степень:
Если вам удалось избежать исчезновения нужных битов, то имейте в виду, что оператор «>>» можно использовать еще и как средство для низведения во вторую степень:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
int x = 1000;
int x = 1000;
int y = x >> 3;  // делим целое число на 8, тем самым получая y = 125
int y = x >> 3;  // делим целое число на 8, тем самым получая y = 125
Строка 83: Строка 82:


<references />
<references />
{{Навигационная таблица/Портал/Arduino}}


[[Категория:Справочник языка Arduino]]
[[Категория:Справочник языка Arduino]]
[[Категория:Побитовые операторы языка Arduino]]
[[Категория:Побитовые операторы языка Arduino]]
[[Категория:Побитовый оператор]]
[[Категория:Побитовый оператор]]

Текущая версия от 12:40, 20 мая 2023

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Операторы побитового сдвига влево (<<) и вправо (>>)[1]

В языке C++ имеется два оператора для побитового сдвига: «<<» (для сдвига влево) и «>>» (для сдвига вправо). Эти операторы заставляют биты из левого операнда сдвинуться влево или вправо на количество позиций, указанных в правом операнде.

Более подробно о побитовых расчетах можно прочесть тут.

Синтаксис

переменная << количество_битов
переменная >> количество_битов

Параметры

переменная (байт, целое, длинное целое), количество_битов (целое <= 32)

Пример

int a = 5;        // в бинарном виде: 0000000000000101
int b = a << 3;   // в бинарном виде: 0000000000101000, или 40 в десятичном
int c = b >> 3;   // в бинарном виде: 0000000000000101, т.е. возврат к 5, с чего мы и начинали

Когда вы смещаете значение X на Y битов влево (X<<Y), то левые биты этого значения теряются, а точнее — вовсе перестают существовать.

int a = 5;        // в бинарном виде: 0000000000000101
int b = a << 14;  // в бинарном виде: 0100000000000000 – первая единица в «101», по сути, просто исчезает

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

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

Например, можно задействовать такие выражения:

1 <<  0  ==    1
1 <<  1  ==    2
1 <<  2  ==    4
1 <<  3  ==    8
...
1 <<  8  ==  256
1 <<  9  ==  512
1 << 10  == 1024
...


Когда вы смещаете значение X на Y битов вправо (X>>Y), и самым первым битом является «1», то результат зависит от того, какому типу данных соответствует значение X. Если X – это целое число, то первый бит будет знаковым битом, который будет определять, будет ли X значением с отрицательным числом или нет. В этом случае знаковый бит (по никому не ведомым причинам, корни которых затерялись где-то в далеком программистском прошлом) копируется в оставшиеся биты:

int x = -16;     // в бинарном виде: 1111111111110000
int y = x >> 3;  // в бинарном виде: 1111111111111110

Эта особенность, именуемая «знаковым расширением», зачастую бывает вовсе не нужна — например, в случаях, когда вы хотите, чтобы слева появлялись не нули, а единицы. Тут необходимо воспользоваться приведением типов данных и с его помощью сделать X беззнаковым целым числом, поскольку на него это знаковое расширение не действует. В результате слева будут появляться биты, скопированные справа:

int x = -16;                   // в бинарном виде: 1111111111110000
int y = (unsigned int)x >> 3;  // в бинарном виде: 0001111111111110

Если вам удалось избежать исчезновения нужных битов, то имейте в виду, что оператор «>>» можно использовать еще и как средство для низведения во вторую степень:

int x = 1000;
int y = x >> 3;   // делим целое число на 8, тем самым получая y = 125

См.также

Внешние ссылки