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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> 64-разрядный сдвиг, warning 
V
    Опции темы
ksili
Дата 5.5.2009, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Вот на такой код
Код

unsigned __int64 *arr_64;
int var;

....

arr_64[i] |= 1 << (var-1)*2;

Компилятор выдаёт warning:
Цитата

warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)

то есть << - это получается 32-разрядный сдвиг? Т.е. сдвиг в 32-битной переменной. Однако мне надо сдвигать именно в 64 разрядах. Т.е. единица может попасть и в старшее двойное слово. А это не выполняется, т.к. нижеследующий код выводит ноль:

Код

    char count_str[20];
    unsigned __int64 sdf = 1 << 32;

    itoa(sdf, count_str, 10);

    cout << count_str;


Может есть оператор для 64-битного сдвига? Я в MSDN-е такого не нашёл.



--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Lazin
Дата 5.5.2009, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Код

unsigned __int64 sdf = 1ui64 << 32;

PM MAIL Skype GTalk   Вверх
ksili
Дата 5.5.2009, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Lazin, а что такой префикс можно использовать? У меня компилятор не понял. 

Но я уже понял, что сдвигать надо тоже 64-битную переменную:
 
Код

arr_64[i] |= (unsigned __int64)1 << (var-1)*2;


Добавлено через 6 минут и 21 секунду
Цитата(Lazin @  5.5.2009,  13:46 Найти цитируемый пост)
1ui64 << 32


Цитата(ksili @  5.5.2009,  13:53 Найти цитируемый пост)
а что такой префикс можно использовать?

Что-то я сегодня туплю. Подумал, что это префикс lui (long unsigned int),  а на самом деле это постфикс ui64.  smile 

Спасибо.

Добавлено через 6 минут и 37 секунд
Цитата(Lazin @  5.5.2009,  13:46 Найти цитируемый пост)
1ui64 << 32


Цитата(ksili @  5.5.2009,  13:53 Найти цитируемый пост)
а что такой префикс можно использовать?

Что-то я сегодня туплю. Подумал, что это префикс lui (long unsigned int),  а на самом деле это постфикс ui64.  smile 

Спасибо.


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Thunderbolt
Дата 8.5.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


DevRel
*


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

Репутация: 10
Всего: 16



Из статьи "20 ловушек переноса Си++ - кода на 64-битную платформу".


5. Операции сдвига

Операции сдвига при невнимательном использовании могут принести много неприятностей во время перехода от 32-битной к 64-битной системе. Начнем с примера функции, выставляющей в переменной типа memsize, указанный вами бит в 1:
Код
ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) {
  ptrdiff_t mask = 1 << bitNum;
  return value | mask;
}


Приведенный код работоспособен на 32-битной архитектуре и позволяет выставлять биты с номерами от 0 до 31. После переноса программы на 64-битную платформу возникнет необходимость выставлять биты от 0 до 63. Как Вы думаете, какое значение вернет следующий вызов функции SetBitN(0, 32)? Если Вы думаете, что 0x100000000, то авторы рады, что не зря подготовили эту статью. Вы получите 0.

Обратите внимание, что "1" имеет тип int и при сдвиге на 32 позиции произойдет переполнение, как показано на рисунке 2.


user posted image
Рисунок 2. Вычисление выражения "ptrdiff_t mask = 1 << bitNum".

Для исправления кода необходимо сделать константу "1" того же типа, что и переменная mask.

Код
ptrdiff_t mask = ptrdiff_t(1) << bitNum;


или
Код
ptrdiff_t mask = CONST3264(1) << bitNum;


Еще один вопрос. Чему будет равен результат вызова неисправленной функции SetBitN(0, 31)? Правильный ответ 0xffffffff80000000. Результатом выражения 1 << 31 является отрицательное число -2147483648. Это число представляется в 64-битной целой переменной как 0xffffffff80000000. Следует помнить и учитывать эффекты сдвига значений различных типов.

....


www.Viva64.com

--------------------
Карпов Андрей, DevRel в PVS-Studio.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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