Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
xoror
29 / 31 / 2
Регистрация: 15.12.2013
Сообщений: 147
#1

Побитовые операции сдвига - C++

26.12.2013, 20:55. Просмотров 587. Ответов 8
Метки нет (Все метки)

Как работают операции сдвига вправо? Я всегда считал что освобождающиеся левые биты заполняются нулями. Оказывается это не всегда так. Если число отрицательное, то эти биты заполняются единицами, т.е. знаковым битом. Это что получается, что освободившиеся биты всегда заполняются именно самым старшим битом или как?

Вот пример программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <windows.h>
#include <stdio.h>
 
 
int WINAPI WinMain(HINSTANCE,  HINSTANCE,  LPSTR,  int)
{
    SHORT       value       = 0x8004;   // 1000 0000 0000 0100 = отрицательное число
    value >>= 2;                        // 1110 0000 0000 0001 = -8191
                                        // 0001 1111 1111 1110
                                        // 0001 1111 1111 1111 = 8191
 
    char        szText[50];
 
    wsprintf(szText,  "%d",  value);
    MessageBox(NULL,  szText,  "",  MB_OK); // -8191 !! Отрицательное число
 
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.12.2013, 20:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Побитовые операции сдвига (C++):

Побитовые операции - C++
Задание: Дано целое неотрицательное число. Определить количество составляющих его шестнадцатеричных цифр, содержащих в двоичном...

Побитовые операции - C++
Задача: битовый образ 8*8 задается при помощи 8 байт, каждый байт состоит, соответственно, из 8 бит, бит={0,1}; при помощи побитовых...

Побитовые операции на с++ (<< и >>) - C++
Подскажите пожалуйста, такая задача - побитовый сдвиг на заданное количество символов сдвигает только цифры, как сделать чтобы он то же...

Побитовые операции - C++
Помогите, не могу понять как сделать эту программу( unsigned ChangeGroupBits(unsigned x, unsigned y, int n1, int n2); ChangeGroupBits–...

Побитовые операции - C++
1-программа #include &lt;stdio.h&gt; #include &lt;windows.h&gt; int main(void) { char g; /* ??? ????????? */ char s; /* ??????? ?????? */ ...

Побитовые операции - C++
Помогите решить несколько задач по битовым операциям,они все малы по реализации. И объяснить начиная с 3 задачи,что нужно сделать?А то не...

8
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
Завершенные тесты: 1
26.12.2013, 22:50 #2

Не по теме:

delete



Добавлено через 10 минут
из эксперимента, для short и если начальное число отрицательное (старший бит 1) при сдвиге вправо, левые биты заполняются 1, для unsigned short для числа 57344 (тут старший бит так же 1) при сдвиге левые биты заполняются нулями, смею предположить что это зависит от того является ли число знаковым или нет и если оно знаковое и отрицательное то при сдвиге вправо заполнение 1ми
1
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
26.12.2013, 23:03 #3
Запустил такой код
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int main()
{
    short value = 0x8004;
    for (int i = 0; i < 32; ++i, value >>= 1)
        std::cout << value << std::endl;
 
    return EXIT_SUCCESS;
}
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-32764
-16382
-8191
-4096
-2048
-1024
-512
-256
-128
-64
-32
-16
-8
-4
-2
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
Как видно с прмера >>= не есть циклический сдвиг или сдвиг битов, это скорее простое деление на 2^n, так как n у меня равно 1, поэтому просто деление на два.

Почему же в бинартой записи появляются 1 вместо 0? Чисто технический ньюнс, согласно которому отрицательные числа сохраняются в другом виде.

Добавлено через 2 минуты
http://ru.wikipedia.org/wiki/%D0%94%...81%D0%BB%D0%B0)
1
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,602
26.12.2013, 23:04 #4
Цитата Сообщение от outoftime Посмотреть сообщение
return EXIT_SUCCESS;
Просто на будущее т.к. вы помогаете тут часто и используете эту конструкцию постоянно в коде:
данный дефайн определен в cstdlib.
Да и не за чем вообще return тут писать, итак по стандарту успех (то бишь 0) вернет.
0
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
26.12.2013, 23:09 #5
aLarman, xoror, Все дело в машинном представлении отрицательных значений, ссылку на вики я предоставил

Добавлено через 1 минуту
MrGluck, ну да, этот макрос есть в <cstdlib> но <iostream> успешно его подключает, так что не вижу проблем.

Добавлено через 2 минуты
MrGluck, http://www.linux.org.ru/forum/development/5301610#comment-5302596
0
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,602
26.12.2013, 23:13 #6
Цитата Сообщение от outoftime Посмотреть сообщение
MrGluck, ну да, этот макрос есть в <cstdlib> но <iostream> успешно его подключает, так что не вижу проблем
не iostream, а компилятор. И причем это зависит от его внутреннего устройства. Железной гарантии нет и правильно явно указывать хедер где объявлен нужный нам дефайн/функция/класс.
1
gazlan
3133 / 1909 / 285
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
27.12.2013, 05:00 #7
Цитата Сообщение от xoror Посмотреть сообщение
Как работают операции сдвига
Арифиметический и логический сдвиг
2
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
Завершенные тесты: 1
27.12.2013, 12:29 #8
Цитата Сообщение от outoftime Посмотреть сообщение
Все дело в машинном представлении отрицательных значений, ссылку на вики я предоставил
я как бы в курсе вопрос больше в том как это происходит, реально ли для сдвига есипользуется целоцисленное деление, или оно происходит по-другому, когда то была инфа в универе, но сейчас в устройстве процессоров могло что то изменится (испю другие алгоритмы), а еще я забыл
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
27.12.2013, 12:51 #9
Когда что-то становится непонятно, имеет смысл обратиться к Стандарту.
5.8/3:
The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed
type and a non-negative value, the value of the result is the integral part of the quotient of E1/2E2. If E1
has a signed type and a negative value, the resulting value is implementation-defined.
Как можно видеть, в случае когда E1 имеет отрицательное значение результат побитового сдвига вправо зависит от реализации компилятора.
1
27.12.2013, 12:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2013, 12:51
Привет! Вот еще темы с ответами:

Побитовые операции - C++
Всем доброго утра. Дана такая задача: есть два чсила,поменять местами 2 последние цифры этих чисел между собой, т.е. 2 последних Х заменить...

Побитовые операции в С++ - C++
Здраствуйте. Нужно написать программу которая будед считывать количество единичек (1) в побитовом представлении числа. Пример input: 15 ...

Побитовые операции - C++
Здравствуйте уважаемые читатели форума! СОвсем не представляю как сделать простейшую програмку на С++. Нужно вычислить номер позиции...

Побитовые операции - C++
От друга услышал идею о побитовой сортировки имен (например). К примеру, если у нас набор структурных переменных с анкетами работников, и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru