2013-08-28 9 views
0

У меня возник вопрос о преобразовании базы с 10 в 2 без использования разделов (/) и модулей (%), поэтому я придумал решение с использованием побитового И (&) и справа сдвига (>>).Десятичная дивизия по левому смену

Итак, я начинаю понимать, что именно делают эти два оператора, но все же для некоторых вопросов я не мог найти ответ или понять логику.

Если я правильно понимаю, что деление работает согласно значению места в десятичной и двоичной единицах. когда мы делим число на 10 или 2, мы сдвигаем значение места на одно место вправо в обоих, что приведет к делению на 10 в десятичной и по двум в двоичном.

Х = 120 (в базе десяти), если Х >> 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 ; 
} 

я comfused причину в моем сознании это было как этот

а = 120 (в базе десяти), если Х >> 1 мы будем иметь Х = 12 (деление на 10)

но результат был этот

а = 120 (в базе десяти), если X >> 1 имеем X = 60 (деление на 2 !!)

Я не понимаю, два основных пункта о результате:

сначала: если этот оператор (>>) просто сдвинет значение места цифр в коде и не изменит базу номера (10), он должен произвести другой результат (12), чем мы можем видеть в результате кода (который это 60). Почему мы можем видеть этот результат (60), но не 12?

второй: если он выполняет двоичный сдвиг влево (что мне кажется это для меня), он меняет десятичную на двоичную сначала с помощью IDE или нет?

и о побитовом И если это логично ворота (который, кажется, что это):

1.How мы можем поставить другое значение, кроме 0 и 1 и стал есть ответ?

побитовое И 2. Согласно правилам

Y & 1 = Y

, то это должно быть 120, а результат кода 1. что такое объяснение этому?

3.может ли это сгенерировать напоминание (согласно которым выполняются математические операции и логика)?

+0

Сдвиги называются «побитовыми», потому что они работают с битами, то есть в базе 2. Числа в C++ обычно хранятся в двоичном формате; они преобразуются в десятичные только для ввода и вывода. –

+0

'int' содержит значение. значения не имеют базы. Поэтому 'a' не находится ни в одной базе. '>>' в C++ всегда является базой 2. Ergo, результирующее значение ... –

ответ

4

>> оператор в C++ всегда делает двоичной перемены, никогда десятичной переключения передач. Оператор десятичной смены не существует. Вы можете написать свою собственную функцию, которая сделает это, если вы этого хотите.

Хотя не стоит думать о математическом делении на 10, как о сдвиге на одно десятичное место, это не так, как C++ делает смещение. Кроме того, он переключается на справа, а не слева - посмотрите, в каком направлении указываются скобки.

Вы также неправильно поняли побитовые определения. Это правда, что Y & 1 = Y, , когда Y бит. Когда Y больше, чем один бит, определение расширяется, чтобы применить однобитовое определение к каждому бит в двух операндах. Это то, что побитовое означает. Оператор применяется поразрядным к операндам: первый бит левого операнда объединяется с первым битом правого операнда, чтобы получить первый бит результата. Аналогично, второй бит каждого из двух операндов определяет второй бит результата и так далее для каждой пары бит в операндах.

Чтобы рассчитать остаток от деления двух чисел, используйте оператор %, также известный как modulo. Подробнее об этом читайте в учебнике на C++.

5

Операторы сдвига в 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, вы просто используете и до разделения с подходящей битовой маской.

BTW, если вы хотите лучше понять, как эти парни работают в двоичном формате, вы можете играть с std::bitset<8>: этот шаблон шаблона имеет одни и те же побитовые операции, может быть построен из целого числа, а при печати отдельные биты.

+0

У меня есть фотография, которую вы сделали, что первое число десятичных чисел inpu изменяется на двоичное значение IDE на кулисах – Felix

1

При чтении ввода с помощью cin >> a есть преобразование символьной строки «120» в целое число 120. В памяти и ЦП целое число (возможно, в зависимости от вашей системы) представлено как 32 бита 00000000 00000000 00000000 01111000. Если вы используете окна, удобный способ увидеть бит-шаблон числа - это калькулятор окон в режиме программиста.

Операция & работает по-разному. В процессоре есть 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».