Há alguma diferença entre 1U e 1 Em C?

    while ((1U << i) < nSize) {
        i++;
    }

alguma razão em particular para usar 1U em vez de 1?

 14
Author: pevik, 2010-11-16

4 answers

Na maioria dos compliers, ambos darão um resultado com a mesma representação. No entanto, de acordo com a especificação C, o resultado de uma operação de mudança de bits em um argumento assinado dá resultados definidos de implementação, então na teoria 1U << i é mais portátil do que 1 << i. Na prática, todos os compiladores C que alguma vez encontrará tratam turnos assinados à esquerda como turnos não assinados à esquerda.

A outra razão é que se nSize não estiver assinado, então comparando-o com um testamento assinado 1 << i gerar um aviso de compilador. Mudar o 1 para 1U livra-se da mensagem de aviso, e não tem de se preocupar com o que acontece se i For 31 ou 63.

O aviso do compilador é provavelmente a razão pela qual 1U aparece no código. Sugiro compilar C com a maioria dos avisos ligados, e eliminar as mensagens de aviso alterando o seu código.

 15
Author: Dietrich Epp, 2010-11-16 09:05:32

1U não está assinado. Pode transportar valores duas vezes maiores, mas sem valores negativos.

Dependendo do ambiente, ao usar U, Eu posso ser um máximo de 31 ou 15, sem causar um excesso. Sem usar U, Eu posso ser um máximo de 30 ou 14.

31, 30 são para 32 bits int
15, 14 são para 16 bits int

 5
Author: AlexanderMP, 2010-11-16 08:59:15

Se nSize é um int, pode ser no máximo de 2147483647 (2^31-1). Se você usar 1 em vez de 1U, então 1 << 30 irá obter 1073741824 e {[4] } será -2147483648, e assim o laço while nunca terminará se nSize for maior que 1073741824.

Com 1U << i, 1U << 31 avaliaremos para 2147483648, e assim você pode usá-lo com segurança para nSize até 2147483647. Se nSize é um int sem sinal, também é possível que o loop nunca termine, como nesse caso nSize pode ser maior do que 1U << 31.

Edit: Então eu discordo com as respostas dizendo que nSize deve ser assinado, mas se for assinado, então não deve ser negativo...

 3
Author: steabert, 2010-11-16 09:21:44

1U não está assinado.

A razão pela qual usaram um valor sem Sinal nessa expressão é (acho que) porque nSize também não está assinado, e os compiladores (quando invocados com certos parâmetros) dão avisos ao comparar valores assinados e não assinados.

Outra razão (menos provável, na minha opinião, mas não podemos saber sem saber o valor wath {[[0]} é suposto assumir) é que os valores não assinados podem ser duas vezes maiores do que os assinados, por isso nSize pode ser até ~4 * 10^9 em vez de ~2*10^9.

 1
Author: peoro, 2010-11-16 09:04:40