Пятница, 29 Ноября 2024, 13:49

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Странно...
vasua99Дата: Понедельник, 05 Ноября 2012, 16:06 | Сообщение # 1
GNU follower
Сейчас нет на сайте
Привет всем smile , есть небольшая программа:

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-ми байтовой переменной)

Проверил - у меня работает как положено smile . Хотя, через переполнение делать - все таки не лучший вариант (на ином железо оно вообще может упасть).

Quote (vasua99)
кажись понял)) если сдвинуть 1 на 64 бита влево, то он уйдет за пределы переменной, но ведь - 1 в итоге дает все равно 2^64 - 1

Если сдвинуть 1 на 64, то произойдет переполнение (все биты сбросятся в 0) и результатом будет 0. А если эта переменная беззнаковая, то делая ей "-1" все биты установятся соответcтвенно в 1 (благодаря представлению "-1" в дополнительном коде) и результатом будет максимально возможное число. Но так таки делать все же не стоит smile


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)

Сообщение отредактировал Archido - Понедельник, 05 Ноября 2012, 19:39
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг