Мне задали вопрос по переводу базы с 10 на 2 без использования деления (/) и модулей (%),поэтому я придумал решение использовать побитовое И (&) и правый сдвиг (>>).
поэтому я начинаю изучать, что именно делают эти два оператора, но все же на некоторые вопросы я не смог найти ответа или понять логику.
Если я правильно понимаю, деление работает в соответствии с местным значением цифр, в десятичном и двоичном виде. когда мы делим число на 10 или 2, мы сдвигаем значение места на одно место вправо в обоих, что приведет к делению на 10 в десятичном виде и на два в двоичном.
X = 120 (из десяти), если X >> 1, мы будем иметь X = 12 (деление на 10)
Y = 1000 (на основе двух), если Y >> 1, мы будем иметь X = 100 (деление на 2)
но когда я использую этот кусок кода:
#include<iostream>
using namespace std ;
int main()
{
int a,b=1;
cout <<"enter an integer"<<endl;
cin>> a;
cout<<(a & b)<<endl;
a=a>>1;
cout<<a;
cout<<endl;
system("pause");
return 0 ;
}
Я запутался, потому что в моем сознании это было так
a = 120 (в базе десяти), если X >> 1, мы будем иметь X = 12 (деление на
10)
но результатом было это
a = 120 (в базе десяти), если X >> 1, мы имеем X = 60 (деление на 2 !!)
Я не понимаю два основных момента о результате:
во-первых: если этот оператор (>>) просто сместит значение цифры в коде и не изменит основание числа (10), он должен дать другой результат (12), чем мы видим в результате кода (который это 60). почему мы можем видеть этот результат (60), но не 12?
второе: если он выполняет двоичное смещение влево (что для меня кажется так), то сначала IDE изменяет десятичное значение на двоичное или нет?
и о побитовом И если это логический элемент (который, кажется, так и есть):
1.Как мы можем поставить другое значение, кроме 0 и 1, и у стали есть ответ?
2. По битовой и правил
Y&1 = Y,
тогда это должно быть 120, но результат кода равен 1. Чем это объясняется?
3. как он может генерировать напоминание (согласно каким математическим операциям и логике)?
Операторы сдвига в C ++ всегда используют базу 2. То есть x >> 1
меняет значение x
одной двоичной цифрой. Тем не менее, обратите внимание, что не стоит переносить целые числа со знаком, так как их значение легко не определено: при игре с битовой логикой вы всегда хотите использовать целые числа без знака, например, unsigned int
или же unsigned long
, Преобразование десятичных значений во внутреннее представление выполняется с помощью операции ввода, которая, кстати, должна быть проверена на успешность:
if (std::cin >> a) {
...
}
else {
std::cerr << "ERROR: failed to read value a\n";
}
Другая бинарная операция (&
за а также, |
за или же, ^
для _xor, и ~
за инвертировать) оперировать отдельными битами. Например, 7u & 13u
доходность 5u
, Чтобы получить остаток от деления на степень 2, вы просто используете а также до деления с подходящей битовой маской.
Кстати, если вы хотите лучше понять, как эти парни работают в двоичном формате, вы можете поиграть с std::bitset<8>
: этот шаблон класса имеет те же побитовые операции, может быть построен из целого числа и при печати показывает отдельные биты.
>>
оператор в C ++ всегда делает двоичный сдвигаясь, никогда десятичный смещение. Там нет десятичного оператора сдвига. Вы можете написать свою собственную функцию, которая делает это, если хотите.
Хотя математическое деление на 10 не является неправильным, если рассматривать сдвиг на одно десятичное место, это не так, как в C ++. Кроме того, он переходит к право, не оставил — посмотрите, куда указывают скобки.
Вы также неправильно поняли побитовые определения. Это правда, что Y & 1 = Y, когда Y немного. Когда Y больше одного бита, определение расширяется, чтобы применить однобитное определение к каждый немного в двух операндах. Это то что побитовое средства. Оператор применяется побитовое к операндам: первый бит левого операнда объединяется с первым битом правого операнда, чтобы получить первый бит результата. Аналогично, вторые биты каждого из двух операндов определяют второй бит результата и так далее для каждой пары битов в операндах.
Чтобы вычислить остаток от деления двух чисел, используйте %
оператор, также известный как по модулю оператор. Узнайте больше об этом в вашем учебнике C ++.
<< и >> операторы являются побитовыми операторами, которые «работают» в базе 2.
http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23
Когда вы читаете ввод cin >> a
происходит преобразование строки символов «120» в целое число 120. В памяти и ЦП целое число (вероятно, в зависимости от вашей системы) представляется как 32 бита 00000000 00000000 00000000 01111000
,
Если вы используете Windows, удобный способ увидеть битовую комбинацию числа — это калькулятор Windows в режиме программирования.
&
операция работает побитно. В ЦП есть 32 логических элемента, которые вычисляют результат для каждой позиции бита:
a = 00000000 00000000 00000000 01111000
b = 00000000 00000000 00000000 00000001
a & b = 00000000 00000000 00000000 00000000
Таким образом, результатом является целое число 0, а не 1, как вы написали.
Еще один пример с b=231
:
Результат 96, только биты в позициях 5 и 6 установлены,
для всех остальных позиций хотя бы один входной бит равен 0.
a = 00000000 00000000 00000000 01111000
b = 00000000 00000000 00000000 11100111
a & b = 00000000 00000000 00000000 01100000
после a = a>>1
все биты сдвинуты на одну позицию вправо.
то, что происходит в крайнем левом бите, зависит от знака, так что
Dietmar рекомендует использовать неподписанные типы данных для
немного манипуляций.
a = 00000000 00000000 00000000 00111100
Когда вы печатаете результат с cout << a
эта битовая комбинация преобразуется обратно в
десятичное представление в виде строки символов «60».
С битовым сдвигом вы работаете в двоичном, а не в десятичном виде.
В памяти 120 хранится в двоичном формате, который = 1111000
сдвинут вправо 1 = 111100 или 60
http://www.binaryhexconverter.com/binary-to-decimal-converter
Демонстрирует сдвиг:
http://www.miniwebtool.com/bitwise-calculator/bit-shift/