while ((1U << i) < nSize) {
i++;
}
Любая конкретная причина использовать 1U
вместо 1
?
while ((1U << i) < nSize) {
i++;
}
Любая конкретная причина использовать 1U
вместо 1
?
У большинства участников, оба будут давать результат с тем же представлением. Однако, согласно спецификации C, результат операции сдвига бит по подписанному аргументу дает результаты, определенные реализацией, поэтому теоретически 1U << i
более портативен, чем 1 << i
. На практике все компиляторы C, с которыми вы когда-либо столкнетесь, обрабатывали сдвинутые левые сдвиги так же, как беззнаковые сдвиги влево.
Другая причина заключается в том, что если nSize
не указано, то сравнение с подписанным 1 << i
будет генерировать предупреждение компилятора. Изменение 1
на 1U
избавляет от предупреждения, и вам не нужно беспокоиться о том, что произойдет, если i
равно 31 или 63.
Предупреждение о компиляторе, скорее всего, является причиной появления 1U
в коде. Я предлагаю компилировать C с включенным большинством предупреждений и устранять предупреждающие сообщения, изменяя ваш код.
1U не имеет знака. Он может переносить значения в два раза большие, но без отрицательных значений.
В зависимости от среды, при использовании U, я может быть максимум 31 или 15, не вызывая переполнения. Без использования U я может быть не более 30 или 14.
31, 30 для 32-битных int
15, 14 для 16 бит int
Если nSize является int
, оно может быть не более 2147483647 (2 ^ 31-1). Если вы используете 1
вместо 1U
, тогда 1 << 30
получит вас 1073741824, а 1 << 31
будет -2147483648, и поэтому цикл while никогда не закончится, если nSize больше 1073741824.
С 1U << i
, 1U << 31
будет оцениваться до 2147483648, и поэтому вы можете безопасно использовать его для nSize до 2147483647. Если nSize является неподписанным int, также возможно, что цикл никогда не заканчивается, как в этом случае nSize может быть больше 1U << 31
.
Изменить: Поэтому я не согласен с ответами, говорящими, что nSize должен быть неподписанным, но если он подписан, то он не должен быть отрицательным...
1U без знака.
Причина, по которой они использовали значение unsigned в этом выражении, является (я думаю), потому что nSize
тоже без знака, а компиляторы (при вызове с определенными параметрами) дают предупреждения при сравнении значений с подписью и без знака.
Другая причина (менее вероятно, по моему мнению, но мы не можем знать, не зная, что значение wath nSize
предполагается предположить) заключается в том, что значения без знака могут быть в два раза больше, чем подписанные, поэтому nSize
может быть до ~ 4 * 10 ^ 9 вместо ~ 2 * 10 ^ 9.