Suponha que eu tenha o número 'numb'=1025 [00000000 00000000 00000100 00000001]
representado:
Na máquina Little-Endian:
00000001 00000100 00000000 00000000
Na máquina Big-Endian:
00000000 00000000 00000100 00000001
Agora, se eu aplicar o Shift Esquerdo em 10 bits (ou seja: numb << = 10), devo ter:
[A] Na máquina Little-Endian:
Como observei no GDB, Little Endian faz a mudança para a esquerda em 3 etapas: [Eu mostrei '3' Steps para entender melhor apenas o processamento]
Trate o não. na Convenção Big-Endian:
00000000 00000000 00000100 00000001
Aplicar Shift à esquerda:
00000000 00010000 00000100 00000000
Represente o resultado novamente em Little-Endian:
00000000 00000100 00010000 00000000
[B] Na máquina Big-Endian:
00000000 00010000 00000100 00000000
Minha pergunta é:
Se eu aplicar diretamente uma mudança à esquerda na Convenção Little Endian, ela deverá fornecer:
numb
:
00000001 00000100 00000000 00000000
numb << 10
:
00010000 00000000 00000000 00000000
Mas, na verdade, fornece:
00000000 00000100 00010000 00000000
Para alcançar apenas o segundo resultado, mostrei três etapas hipotéticas acima.
Por favor, explique-me por que os dois resultados acima são diferentes: O resultado real de numb << 10
é diferente do resultado esperado.
fonte
Não, o deslocamento de bits, como qualquer outra parte de C, é definido em termos de valores , não de representações. O desvio à esquerda por 1 é a multiplicação por 2, o desvio à direita é a divisão. (Como sempre, ao usar operações bit a bit, tenha cuidado com a assinatura. Tudo está mais bem definido para tipos integrais não assinados.)
fonte
x &= -1u << 20
, provavelmente estará incorreto sex
tiver 64 bits eint
32 bits. Por esse motivo, o GCC promete nunca tratar os turnos assinados como indefinidos ou mesmo não especificados.Qualquer instrução de deslocamento que desloque primeiro os bits de ordem superior é considerada o deslocamento esquerdo. Qualquer instrução de mudança que desloque primeiro os bits de ordem inferior é considerada a mudança certa. Nesse sentido, o comportamento de
>>
e<<
para osunsigned
números não dependerá da persistência.fonte
Os computadores não escrevem números da maneira que fazemos. O valor simplesmente muda. Se você insistir em examiná-lo byte a byte (mesmo que não seja assim que o computador faz), você poderia dizer que em uma máquina little-endian, o primeiro byte muda para a esquerda, o excesso de bits entra no segundo byte, e assim por diante.
(A propósito, little-endian faz mais sentido se você escrever os bytes verticalmente e não horizontalmente, com endereços mais altos no topo. O que acontece é como os diagramas de mapas de memória são comumente desenhados.)
fonte
Embora a resposta aceita indique que endianess é um conceito da visão da memória. Mas não acho que isso responda diretamente à pergunta.
Algumas respostas me dizem que as operações bit a bit não dependem de endianess , e o processador pode representar os bytes de qualquer outra maneira. De qualquer forma, está falando que endianess é abstraída.
Mas quando fazemos alguns cálculos bit a bit no papel, por exemplo, não precisamos declarar a endianess em primeiro lugar? Na maioria das vezes escolhemos implicitamente uma endianess.
Por exemplo, suponha que temos uma linha de código como esta
0x1F & 0xEF
Como você calcularia o resultado manualmente, em um papel?
Então, aqui usamos um formato Big Endian para fazer o cálculo. Você também pode usar Little Endian para calcular e obter o mesmo resultado.
Aliás, quando escrevemos números em código, acho que é como um formato Big Endian.
123456
ou0x1F
, os números mais significativos começam da esquerda.Novamente, assim que escrevemos um formato binário de um valor no papel, acho que já escolhemos uma Endianess e estamos vendo o valor como o vemos na memória.
Então, voltando à questão, uma operação de mudança
<<
deve ser pensada como uma mudança de LSB (byte menos significativo) para MSB (byte mais significativo) .Então, como no exemplo da pergunta:
numb=1025
Pequeno endian
LSB 00000001 00000100 00000000 00000000 MSB
Então,
<< 10
seria10bit
mudar de LSB para MSB.Comparação e
<< 10
operações para o formato Little Endian passo a passo:Uau! Eu recebo o resultado esperado conforme o OP descrito!
Os problemas que o OP não obteve o resultado esperado são:
Parece que ele não mudou do LSB para o MSB.
Ao mudar bits no formato Little Endian, você deve perceber (graças a Deus eu entendi) que:
LSB 10000000 00000000 MSB << 1
éLSB 00000000 00000001 MSB
, nãoLSB 01000000 00000000 MSB
Porque para cada indivíduo
8bits
, na verdade, estamos escrevendo em umMSB 00000000 LSB
formato Big Endian.Então é como
LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB
Resumindo:
Embora as operações bit a bit sejam abstraídas blablablabla ..., quando calculamos as operações bit a bit manualmente, ainda precisamos saber qual endianess estamos usando ao escrever o formato binário no papel. Também precisamos garantir que todos os operadores usem a mesma resistência.
O OP não obteve o resultado esperado porque ele fez a mudança errada.
fonte