Есть ли разница между 1U и 1 в C? - PullRequest
15 голосов
/ 16 ноября 2010
    while ((1U << i) < nSize) {
        i++;
    }

Любая конкретная причина использовать 1U вместо 1?

Ответы [ 4 ]

17 голосов
/ 16 ноября 2010

На большинстве компиляторов оба будут давать результат с одинаковым представлением. Однако, согласно спецификации C, результат операции сдвига битов со знаковым аргументом дает результаты, определенные реализацией, поэтому в теории 1U << i является более переносимым, чем 1 << i. На практике все компиляторы Си, с которыми вы когда-либо сталкивались, обращаются со знаковыми левыми сдвигами так же, как со знаковыми левыми сдвигами.

Другая причина заключается в том, что если nSize не подписано, то сравнение его со знаком 1 << i вызовет предупреждение компилятора. Изменение 1 на 1U избавляет от предупреждающего сообщения, и вам не нужно беспокоиться о том, что произойдет, если i равно 31 или 63.

Предупреждение компилятора, скорее всего, является причиной появления в коде 1U. Я предлагаю компилировать C с большинством включенных предупреждений и удалять предупреждающие сообщения путем изменения кода.

5 голосов
/ 16 ноября 2010

1U не подписано. Он может нести значения вдвое больше, но без отрицательных значений.

В зависимости от среды, при использовании U, я могу быть максимум 31 или 15, не вызывая переполнения. Без использования U, я могу быть максимум 30 или 14.

31, 30 для 32-битного целого
15, 14 для 16-битного целого

4 голосов
/ 16 ноября 2010

Если 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 - это целое число без знака, также возможно, что цикл никогда не закончится, так как в этом случае nSize может быть большечем 1U << 31.

Редактировать: Так что я не согласен с ответами о том, что nSize должен быть без знака, но если он подписан, то он не должен быть отрицательным ...

1 голос
/ 16 ноября 2010

1U - без знака.

Причиной, по которой они использовали значение без знака в этом выражении, является (я думаю), потому что nSize тоже без знака, и компиляторы (при вызове с определенными параметрами) выдают предупреждения, когдаСравнение значений со знаком и без знака.

Другая причина (на мой взгляд, менее вероятная, но мы не можем знать, не зная, какое значение nSize предполагается), состоит в том, что значения без знака могут быть в два раза больше, чемсо знаком, поэтому nSize может быть до ~ 4 * 10 ^ 9 вместо ~ 2 * 10 ^ 9.

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