в чем разница между определениями макросов: «#define my_macro (1 << 16)» и «#define my_macro (1U << 16)» - PullRequest
0 голосов
/ 14 июля 2011

Я могу предположить, что последний явно указывает на то, что трактовать '1' нужно как целое число без знака.Но каковы плохие побочные эффекты, если какой-либо из первых.Я вижу, что оба они используются в ядре Linux.Так какой из них является более точным / рекомендуемым и почему?

Ответы [ 2 ]

3 голосов
/ 14 июля 2011

Одна проблема с 1 << x становится очевидной, когда вы сдвигаете 1 достаточно далеко влево.На машинах с двойным представлением для целых чисел это значение внезапно становится отрицательным.Предполагая, что int ширина 32 бита:

#include <stdio.h>

int
main(int argc, const char** argv) 
{
    printf("%d\n", (1 << 30));
    printf("%d\n", (1 << 31));
    printf("%ud\n", (1U << 30));
    printf("%ud\n", (1U << 31));        
    return 0;
}

дает

1073741824
-2147483648
1073741824d
2147483648d

на моей машине.Это может быть неожиданным в других частях кода.В частности, поскольку обратный сдвиг не обязательно эквивалентен из-за расширения со знаком:

#include <stdio.h>

int
main(int argc, const char** argv) 
{
    printf("%d\n", (2 << 29) >> 29);
    printf("%d\n", (2 << 30) >> 30);
    printf("%u\n", (2U << 29) >> 29);
    printf("%u\n", (2U << 30) >> 30);
    return 0;
}

приводит к

2
-2 
2 
2

Обратите внимание, что он перевернул знак на второй выходной строке ...

1 голос
/ 14 июля 2011

Это зависит от системы, в которой вы это используете.
Если это система, в которой целые числа являются 16-разрядными, то (1 << 16) «уйдет за грань», а число будет равно 0. В 32-разрядной системе число будет равно 2 ^ 16 (65536). </p>

Поскольку сдвиг равен 16, тогда действительно не имеет значения, является ли 1 беззнаковым или нет.
Однако, если сдвиг должен быть 15, то это более сложно:

16-разрядное целое число без знака после сдвига будет иметь значение 2 ^ 15 (32768), а 16-разрядное целое число со знаком будет иметь значение -2 ^ 15 (-32768) в представлении с двойным дополнением. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...