Странная проблема с функцией, которая получает машинное слово - PullRequest
0 голосов
/ 05 июня 2011

Вчера я написал функцию для получения машинного слова в Си, но, похоже, в этом что-то не так.

Вот код:

unsigned machineword()
{
int i = 1;
unsigned temp;
while (temp > 0)
{
    i++;
    temp = (unsigned)(~0 >> i);
}
return i;
}

Ответы [ 3 ]

3 голосов
/ 05 июня 2011

Самый простой способ получить ширину unsigned int - это (sizeof(unsigned)*CHAR_BIT).

РЕДАКТИРОВАТЬ: как отмечает pmg, вы должны знать о теоретической разнице между размером, который принимает unsignedпамять и количество битов, доступных для вычислений.Ваш оригинальный код пытается вычислить последний, как и программа ниже.Приведенный выше трюк вычисляет пространство, занимаемое в памяти.

Не очень удобно вычислять это число с >>, поскольку в C запрещено использовать >> с числом, равным или превышающим размерв битах типа вы меняете.Вы можете обойти это, если знаете, что long long строго больше, чем int, вычисляя с помощью unsigned long long:

unsigned machineword()
{
  int i = 1;
  unsigned temp=1;
  while (temp > 0)
  {
    i++;
    temp = (unsigned)(((unsigned long long)~(0U)) >> i);
  }
  return i;
}
1 голос
/ 05 июня 2011

Для вычисления количества битов вы можете использовать CHAR_BIT или UINT_MAX.
Подход CHAR_BIT дает вам количество битов, которые каждое значение занимает в памяти.
Подход UINT_MAX дает вам эффективные доступные биты.

Обычно оба значения будут одинаковыми

#include <limits.h>
#include <stdio.h>

int main(void) {
  unsigned tmp = UINT_MAX;
  int i = 0;
  while (tmp) {
      i++;
      tmp /= 2;
  }
  printf("value bits in a unsigned: %d\n", i);
  printf("memory bits in a unsigned: %d\n", CHAR_BIT * (int)sizeof (unsigned));
  return 0;
}
1 голос
/ 05 июня 2011

Самый простой способ избежать UB при переключении на слишком большое значение при сохранении вашей структуры:

unsigned machineword()
{
   unsigned i = 0;
   unsigned temp = ~0U;
   while (temp > 0)
   {
      i++;
      temp >>= 1;
   }
   return i;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...