Странно...
|
|
vasua99 | Дата: Понедельник, 05 Ноября 2012, 16:06 | Сообщение # 1 |
GNU follower
Сейчас нет на сайте
| Привет всем , есть небольшая программа:
Code #include <iostream> using namespace std;
long long GetMaxValue(int NBit);
int main() { long long _64bit; int _32bit; short _16bit; cout << "_64bit max: " << GetMaxValue(sizeof(_64bit) * 8); cout << "\n_32bit max: " << GetMaxValue(sizeof(_32bit) * 8); cout << "\n_16bit max: " << GetMaxValue(sizeof(_16bit) * 8); cout << endl; return 0; }
long long GetMaxValue(int NBit) { if(!NBit) return 1; else return 2 * GetMaxValue(NBit - 1); }
Но при выполнении выдает(Внимание!): Code _64bit max: 0(!) _32bit max: 4294967296 _16bit max: 65536
Вопрос: почему?на переполнение вроде не похоже...
Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
|
|
| |
falcoware | Дата: Понедельник, 05 Ноября 2012, 16:16 | Сообщение # 2 |
старожил
Сейчас нет на сайте
| GetMaxValue что возращает? Правильно int. И как же не переполнение то?
|
|
| |
Archido | Дата: Понедельник, 05 Ноября 2012, 17:39 | Сообщение # 3 |
Сэнсэй
Сейчас нет на сайте
| Quote (falcoware) Вопрос: почему?на переполнение вроде не похоже... Очень даже похоже. Там везде лишняя единичка.
_16bit max: 65536 - 2 байта вмещают числа от 0 до 65535, 65536 - это уже 0, то самое переполнение _32bit max: 4294967296 - и тут, верхняя граница - 4294967295
Если заменишь тип возвращаемого значения у ф-ции GetMaxValue на int, то ноль будет у 64 и 32 (переполнение у 32). Если заменить тип на short, то нули будут везде.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
vasua99 | Дата: Понедельник, 05 Ноября 2012, 17:58 | Сообщение # 4 |
GNU follower
Сейчас нет на сайте
| возвращаеммое значение то long long(64 бита) Добавлено (05.11.2012, 17:58) --------------------------------------------- так тоже не работает:
Code #include <iostream> using namespace std;
typedef unsigned long long ULINT; // Unsigned longer int
ULINT GetMaxValue(int NBit);
int main() { long long _64bit; int _32bit; short _16bit; cout << "_64bit max: " << GetMaxValue(sizeof(_64bit) * 8); cout << "\n_32bit max: " << GetMaxValue(sizeof(_32bit) * 8); cout << "\n_16bit max: " << GetMaxValue(sizeof(_16bit) * 8); cout << endl; return 0; }
ULINT GetMaxValue(int NBit) { if(!NBit) return 1; else return 2 * GetMaxValue(NBit - 1); }
Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
|
|
| |
Archido | Дата: Понедельник, 05 Ноября 2012, 18:04 | Сообщение # 5 |
Сэнсэй
Сейчас нет на сайте
| И не будет, ибо нужен тип данных, который вмещает более 8-ми байт, а unsigned long long как раз занимает ровно 8... он просто без знака.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
vasua99 | Дата: Понедельник, 05 Ноября 2012, 18:18 | Сообщение # 6 |
GNU follower
Сейчас нет на сайте
| переписал, теперь работает, но!
Code _64bit max: 18446744073709551615 _32bit max: 18446744073709551615 _16bit max: 65535
код:
Code #include <iostream> using namespace std;
unsigned long long GetMaxValue(int NBit);
int main() { long long _64bit; int _32bit; short _16bit; cout << "_64bit max: " << GetMaxValue(sizeof(_64bit) * 8); cout << "\n_32bit max: " << GetMaxValue(sizeof(_32bit) * 8); cout << "\n_16bit max: " << GetMaxValue(sizeof(_16bit) * 8); cout << endl; return 0; }
unsigned long long GetMaxValue(int NBit) { unsigned long long Value = 0; for(NBit--; NBit >= 0; NBit--) Value |= (1 << NBit); return Value; } Добавлено (05.11.2012, 18:18) --------------------------------------------- Самое интересное:
Code unsigned long long GetMaxValue(int NBit) { unsigned long long Value = 0; for(NBit--; NBit >= 0; NBit--) Value |= (1 << NBit); Value = ~Value; return Value; }
Code _64bit max: 0 _32bit max: 0 _16bit max: 18446744073709486080
Порядок хранения байтов?
Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
|
|
| |
Archido | Дата: Понедельник, 05 Ноября 2012, 18:37 | Сообщение # 7 |
Сэнсэй
Сейчас нет на сайте
| Думаю, что нужно как-то так: Code unsigned long long GetMaxValue(int NBit) { unsigned long long Value = 0; for(NBit--; NBit >= 0; NBit--) Value |= ((unsigned long long)1 << NBit); return Value; }
ибо "1" - это таки будет тип intДобавлено (05.11.2012, 18:37) --------------------------------------------- А я бы сделал вообще так:
Code unsigned long long GetMaxValue(int NBit) { return ((unsigned long long)1 << NBit) - 1; }
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
vasua99 | Дата: Понедельник, 05 Ноября 2012, 18:48 | Сообщение # 8 |
GNU follower
Сейчас нет на сайте
| Code unsigned long long GetMaxValue(int NBit) { unsigned long long Value{}; for(NBit--; NBit >= 0; NBit--) Value |= ((unsigned long long)1 << NBit); return Value; }
теперь все правильно, но я все таки не пойму изза чего у 32 битного числа получалось такое большое число? изаа little-endian?Добавлено (05.11.2012, 18:45) ---------------------------------------------
Code unsigned long long GetMaxValue(int NBit) { return ((unsigned long long)1 << NBit) - 1; }
почему-то выдает 0 для 8-ми байтовой переменной)Добавлено (05.11.2012, 18:48) --------------------------------------------- кажись понял)) если сдвинуть 1 на 64 бита влево, то он уйдет за пределы переменной, но ведь - 1 в итоге дает все равно 2^64 - 1
Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
|
|
| |
Archido | Дата: Понедельник, 05 Ноября 2012, 19:07 | Сообщение # 9 |
Сэнсэй
Сейчас нет на сайте
| Quote (vasua99) теперь все правильно, но я все таки не пойму изза чего у 32 битного числа получалось такое большое число? изаа little-endian? Там все дело в преобразовании между знаковой и беззнаковой переменной.
Quote (vasua99) почему-то выдает 0 для 8-ми байтовой переменной) Проверил - у меня работает как положено . Хотя, через переполнение делать - все таки не лучший вариант (на ином железо оно вообще может упасть).
Quote (vasua99) кажись понял)) если сдвинуть 1 на 64 бита влево, то он уйдет за пределы переменной, но ведь - 1 в итоге дает все равно 2^64 - 1 Если сдвинуть 1 на 64, то произойдет переполнение (все биты сбросятся в 0) и результатом будет 0. А если эта переменная беззнаковая, то делая ей "-1" все биты установятся соответcтвенно в 1 (благодаря представлению "-1" в дополнительном коде) и результатом будет максимально возможное число. Но так таки делать все же не стоит
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Сообщение отредактировал Archido - Понедельник, 05 Ноября 2012, 19:39 |
|
| |