Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Некорректная работа операции сдвига 
V
    Опции темы
bsa
Дата 4.3.2010, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Код
#include <iostream>

int main()
{
    unsigned x;
    unsigned y = 32;
    unsigned mask = 1 << 31;
    x = mask << y;
    std::cout << std::hex << "0x" << x << " 0x" << (unsigned(1) << 32) << " 0x" << mask << " 0x" << y << std::endl;
}
Этот код, собранный gcc, выдает у меня:
Код
0x80000000 0x0 0x80000000 0x20
Хотя, по идее, должен выдавать 0 первым числом.

Я что-то не знаю?

Это сообщение отредактировал(а) bsa - 4.3.2010, 15:12
PM   Вверх
Albor
Дата 4.3.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: нет
Всего: 9



Вот это, второе значение выводит как 0х0
Код

std::cout << std::hex << "0x" <<((unsigned) x) << " 0x" << ((0x80000000) << 32) << " 0x" << mask << " 0x" << y << std::endl;

А вот это - как 0х80000000
Код

std::cout << std::hex << "0x" <<((unsigned) x) << " 0x" << ((0x80000000) << y) << " 0x" << mask << " 0x" << y << std::endl;

Получается, что данный глюк происходит из-за переменной

Добавлено @ 15:44
Хе, а при y=31  выдаёт 0

Это сообщение отредактировал(а) Albor - 4.3.2010, 15:45
PM MAIL ICQ   Вверх
bsa
Дата 4.3.2010, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



кстати. я в примере ошибся с направлением операции сдвига. Нужно использовать сдвиг вправо в строке 8.
Код
#include <iostream>
int main()
{
    unsigned x;
    unsigned y = 32;
    unsigned mask = 1 << 31;
    unsigned z = mask >> (y-1);
    x = mask >> y;
    std::cout << std::hex << "0x" << x << " 0x" << (unsigned(1) << 32) << " 0x" << mask << " 0x" << y << " 0x" << z << std::endl;
}
Выводит:
Код
0x80000000 0x0 0x80000000 0x20 0x1

PM   Вверх
Albor
Дата 4.3.2010, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: нет
Всего: 9



Выходит, что без разницы куда сдвигать на у, и так и эдак получается один и тот же результат
PM MAIL ICQ   Вверх
borisbn
Дата 4.3.2010, 18:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Из стандарта C++
Код

The behavior is undefined if the right operand is negative, or greater than or equal to
the length in bits of the promoted left operand


У меня msvc, и ваш код выглядет в ассемблере следующим образом
Код

; 58   :     x = mask >> 32;

  00492    8b 4d e0     mov     ecx, DWORD PTR _mask$[ebp]
  00495    c1 e9 20     shr     ecx, 32            ; 00000020H
  00498    89 4d e4     mov     DWORD PTR _x$[ebp], ecx

; 59   :     x = 1 << 32;

  0049b    c7 45 e4 00 00
    00 00         mov     DWORD PTR _x$[ebp], 0




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 4.3.2010, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



borisbn, цитаты из стандарта достаточно для меня. Спасибо.
PM   Вверх
xvr
Дата 7.3.2010, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата

У меня msvc, и ваш код выглядет в ассемблере следующим образом

Интересует код для x = mask << y;. Скорее всего там shl ?,ecx, где в ecx будет загружен y. Насколько я помню, IA32 использует в операциях shl/shr только 5 младших битов ecx. Так что 32 в y(а значит и в ecx) для него эквивалентны 0


PM MAIL   Вверх
borisbn
Дата 7.3.2010, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



xvr, вы верно предположили про cx (правда cl, а не ecx, но думаю это не играет роли)
Код

; 55   :     x = mask << y;    

  00469    8b 45 e0     mov     eax, DWORD PTR _mask$[ebp]
  0046c    8b 4d e8     mov     ecx, DWORD PTR _y$[ebp]
  0046f    d3 e0         shl     eax, cl
  00471    89 45 e4     mov     DWORD PTR _x$[ebp], eax


Цитата(xvr @  7.3.2010,  16:52 Найти цитируемый пост)
Насколько я помню, IA32 использует в операциях shl/shr только 5 младших битов ecx

получается на другом процессоре это может работать по-другому?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 7.3.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  7.3.2010,  16:17 Найти цитируемый пост)
получается на другом процессоре это может работать по-другому?

 smile , поэтому стандарт и не предписывает определенного поведения в этом вопросе.



--------------------
PM MAIL WWW   Вверх
xvr
Дата 7.3.2010, 17:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(borisbn @ 7.3.2010,  17:17)
получается на другом процессоре это может работать по-другому?

Угу, стандарт тут по этому поводу уже цитировали - behavior is undefined
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0550 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.