Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
xoror
 Аватар для xoror
29 / 31 / 2
Регистрация: 15.12.2013
Сообщений: 147
26.12.2013, 20:55     Побитовые операции сдвига #1
Как работают операции сдвига вправо? Я всегда считал что освобождающиеся левые биты заполняются нулями. Оказывается это не всегда так. Если число отрицательное, то эти биты заполняются единицами, т.е. знаковым битом. Это что получается, что освободившиеся биты всегда заполняются именно самым старшим битом или как?

Вот пример программы
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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.12.2013, 20:55     Побитовые операции сдвига
Посмотрите здесь:

побитовые операции C++
C++ Побитовые операции
C++ Побитовые операции
Побитовые операции C++
C++ Побитовые операции
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
aLarman
636 / 557 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
26.12.2013, 22:50     Побитовые операции сдвига #2

Не по теме:

delete



Добавлено через 10 минут
из эксперимента, для short и если начальное число отрицательное (старший бит 1) при сдвиге вправо, левые биты заполняются 1, для unsigned short для числа 57344 (тут старший бит так же 1) при сдвиге левые биты заполняются нулями, смею предположить что это зависит от того является ли число знаковым или нет и если оно знаковое и отрицательное то при сдвиге вправо заполнение 1ми
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
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)
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,416
26.12.2013, 23:04     Побитовые операции сдвига #4
Цитата Сообщение от outoftime Посмотреть сообщение
return EXIT_SUCCESS;
Просто на будущее т.к. вы помогаете тут часто и используете эту конструкцию постоянно в коде:
данный дефайн определен в cstdlib.
Да и не за чем вообще return тут писать, итак по стандарту успех (то бишь 0) вернет.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
26.12.2013, 23:09     Побитовые операции сдвига #5
aLarman, xoror, Все дело в машинном представлении отрицательных значений, ссылку на вики я предоставил

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

Добавлено через 2 минуты
MrGluck, http://www.linux.org.ru/forum/develo...omment-5302596
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,416
26.12.2013, 23:13     Побитовые операции сдвига #6
Цитата Сообщение от outoftime Посмотреть сообщение
MrGluck, ну да, этот макрос есть в <cstdlib> но <iostream> успешно его подключает, так что не вижу проблем
не iostream, а компилятор. И причем это зависит от его внутреннего устройства. Железной гарантии нет и правильно явно указывать хедер где объявлен нужный нам дефайн/функция/класс.
gazlan
2861 / 1809 / 272
Регистрация: 27.08.2010
Сообщений: 4,896
Записей в блоге: 1
27.12.2013, 05:00     Побитовые операции сдвига #7
Цитата Сообщение от xoror Посмотреть сообщение
Как работают операции сдвига
Арифиметический и логический сдвиг
aLarman
636 / 557 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
27.12.2013, 12:29     Побитовые операции сдвига #8
Цитата Сообщение от outoftime Посмотреть сообщение
Все дело в машинном представлении отрицательных значений, ссылку на вики я предоставил
я как бы в курсе вопрос больше в том как это происходит, реально ли для сдвига есипользуется целоцисленное деление, или оно происходит по-другому, когда то была инфа в универе, но сейчас в устройстве процессоров могло что то изменится (испю другие алгоритмы), а еще я забыл
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2013, 12:51     Побитовые операции сдвига
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
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 имеет отрицательное значение результат побитового сдвига вправо зависит от реализации компилятора.
Yandex
Объявления
27.12.2013, 12:51     Побитовые операции сдвига
Ответ Создать тему
Опции темы

Текущее время: 02:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru