Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > (double)(1 << 32) == 0 почему, когда double 8 байт


Автор: Royan 1.2.2006, 05:31
Не могу понять, почему я не могу присвоить double число 1<<32? Я же не с интом работаю, и sizeof честно говорит 8 байт, в чем проблема?
Система WinXP home (ясное дело win32) компилирую VS2003

Автор: chaos 1.2.2006, 07:32
Цитата

побитовые операции применяются к целочисленым типам(возможно с unsigned)

Добавлено @ 07:34
и интересно почему твой компилер не дал тебе по рукам smile

Автор: Mayk 1.2.2006, 08:09
Цитата(Royan @ 1.2.2006, 09:31 Найти цитируемый пост)

Не могу понять, почему я не могу присвоить double число 1<<32? Я же не с интом работаю, и sizeof честно говорит 8 байт, в чем проблема?
Система WinXP home (ясное дело win32) компилирую VS2003

Код

double d = 1 << 32;

Оно не заработает. 1<<32 - это ещё int, а не double.
Решение
Код

#include <iostream>
using namespace std;
int main()
{
        double s = 1 << 32;
        cout << s << endl; //0

        s = 1LL << 32; //(1)
        cout << s << endl; //4.29497e+09

        s = 0x1p32;  //(2)
        cout << s << endl;//4.29497e+09 

}

способ (2) имхо предпочтительнее. 0x1p32 это уже float constant. а 1LL <<32 это ещё integer constant.
Добавлено @ 08:14
(0x1p32 это 1 * 2 ** 32 - это вообще фича c99, поэтому с++ компилятор может её не держать(комо в с++ стрикт не держит, в с99 держит, gnu c держит, как обстоят с этим делом дела у msvc не знаю. Но если 0x1p32 в нём есть, то это одназначно то, что нужно)).
Добавлено @ 08:18
(только long long (1LL) он тоже не стандартен строго говоря. Если 1LL вызывает ошибку, то можно что-то типа __int64(1) << 32, или __i64(1) << 32. Вообщем shift'ить нужно 64 и более битовое число)
Добавлено @ 08:20
Цитата(chaos @ 1.2.2006, 11:32 Найти цитируемый пост)

и интересно почему твой компилер не дал тебе по рукам

Он максимум что warning выдаст.
Comeau: "ComeauTest.c", line 1: warning: shift count is too large
GCC: a.cpp:7: warning: left shift count >= width of type

Автор: Mayk 1.2.2006, 08:29
Ну или вот так ещё.
Код

        s = double(UINT_MAX) + 1;
        cout << s << endl;
        s = double(numeric_limits<unsigned int>::max()) + 1
        cout << s << endl;


Автор: Royan 2.2.2006, 16:58
Mayk

Спасибо за разъяснения. Тут проблема была не в том, что мне нужно именно получить число 2^32, а в том, что я не понимал почему мне не двинуть больше четырех байт. Мысль о том, что я работаю с интом, а не с double пришла только после того как я проникся содержанием твоего сообщения smile
В силу того что сдвиг на 32 бита я привел как пример, (мне же надо лаконично записывая двигать разное число) я решил использовать __i64(1) << 32. Жаль это сводит переносимость кода только к компиляторам msvc, но пока этого хватит, потом подумаю над тем как изменить кастинг, чтобы он был понятен большему числу компиляторов

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)