내가 숫자를 'numb'=1025 [00000000 00000000 00000100 00000001]
표현 했다고 가정 해보십시오 .
리틀 엔디 언 머신에서 :
00000001 00000100 00000000 00000000
빅 엔디안 머신에서 :
00000000 00000000 00000100 00000001
이제 10 비트에 왼쪽 시프트를 적용하면 (즉 : numb << = 10) 다음을 가져야합니다.
[A] Little-Endian 머신에서 :
GDB에서 알 수 있듯이 Little Endian은 왼쪽 이동을 3 단계로 수행합니다.
-
아니오를 취급하십시오. 빅 엔디안 컨벤션에서 :
00000000 00000000 00000100 00000001
-
왼쪽-시프트 적용 :
00000000 00010000 00000100 00000000
-
Little-Endian에서 결과를 다시 나타냅니다.
00000000 00000100 00010000 00000000
[비]. 빅 엔디안 머신에서 :
00000000 00010000 00000100 00000000
내 질문은 :
리틀 엔디안 컨벤션에 직접 왼쪽 쉬프트를 적용하면 다음과 같이됩니다.
numb
:
00000001 00000100 00000000 00000000
numb << 10
:
00010000 00000000 00000000 00000000
그러나 실제로는 다음을 제공합니다.
00000000 00000100 00010000 00000000
두 번째 결과 만 달성하기 위해 위의 세 가지 가상 단계를 보여주었습니다.
위의 두 결과가 다른 이유를 설명해주십시오. 실제 결과 numb << 10
가 예상 결과와 다릅니다.
답변
엔디안은 값이 메모리에 저장되는 방식입니다. 엔디안과 상관없이 프로세서에로드 될 때 비트 시프트 명령은 프로세서 레지스터의 값에서 작동합니다. 따라서, 메모리에서 프로세서로의 로딩은 빅 엔디안으로 변환하는 것과 동일하며, 시프 팅 동작은 다음에오고 새로운 값은 메모리에 다시 저장되는데, 여기서 리틀 엔디안 바이트 순서가 다시 적용됩니다.
@jww 덕분에 업데이트 : PowerPC에서 벡터 이동 및 회전은 엔디안에 민감합니다. 벡터 레지스터에 값을 가질 수 있으며 시프트 는 little-endian 및 big-endian에서 다른 결과를 생성 합니다.
답변
C의 다른 부분과 마찬가지로 비트 시프트는 표현이 아닌 값으로 정의됩니다 . 1만큼 왼쪽 이동은 2로 곱셈되고 오른쪽 이동은 나눗셈입니다. (비트 단위 연산을 사용할 때와 마찬가지로 부호를주의하십시오. 모든 것이 부호없는 정수 유형에 대해 가장 잘 정의되어 있습니다.)
답변
어떤 시프트 명령이 더 높은 비트를 먼저 시프트하는지는 왼쪽 시프트로 간주됩니다. 어떤 시프트 명령이 하위 비트를 먼저 시프트 시키는가 올바른 시프트로 간주됩니다. 그런 의미에서의 동작 >>
과 <<
에 대한 unsigned
번호 엔디안에 의존하지 않습니다.
답변
컴퓨터는 우리가하는 방식대로 숫자를 쓰지 않습니다. 값은 단순히 이동합니다. 바이트 단위로 보겠다고 주장하면 (컴퓨터가 그렇게하는 방식은 아니지만) 리틀 엔디안 컴퓨터에서 첫 번째 바이트가 왼쪽으로 이동하고 초과 비트는 두 번째 바이트로 이동한다고 말할 수 있습니다. 등등.
(반드시, 리틀 엔디안은 더 높은 주소를 가진 수평이 아닌 수직으로 바이트를 쓰면 더 의미가 있습니다. 메모리 맵 다이어그램이 일반적으로 그려지는 방식입니다.)
답변
수용 된 대답은 엔디안이 메모리 관점의 개념이라고 지적합니다. 그러나 나는 그것이 그 질문에 직접 대답한다고 생각하지 않습니다.
일부 답변에 따르면 비트 단위 연산은 endianess에 의존하지 않으며 프로세서는 다른 방식으로 바이트를 나타낼 수 있습니다. 어쨌든, 그것은 엔디안이 추상화되는 것에 대해 이야기하고 있습니다.
그러나 예를 들어 종이에서 비트 단위로 계산할 때 엔디안을 먼저 언급 할 필요가 없습니까? 대부분의 경우 우리는 내재적으로 엔디안을 선택합니다.
예를 들어, 이와 같은 코드가 있다고 가정
0x1F & 0xEF
종이로 손으로 결과를 어떻게 계산할까요?
MSB 0001 1111 LSB
1110 1111
result: 0000 1111
여기에서는 빅 엔디안 형식을 사용하여 계산을 수행합니다. Little Endian을 사용하여 동일한 결과를 계산하고 얻을 수도 있습니다.
Btw, 코드로 숫자를 쓸 때 빅 엔디안 형식과 같다고 생각합니다. 123456
또는 0x1F
가장 중요한 숫자는 왼쪽에서 시작합니다.
다시, 종이에 이진 형식의 값을 쓰 자마자 우리는 이미 Endianess를 선택했으며 메모리에서 볼 때 가치를보고 있다고 생각합니다.
다시 질문으로 돌아 가면, 시프트 연산 <<
은 LSB (최하위 바이트)에서 MSB (최고 바이트) 로 이동하는 것으로 생각해야합니다 .
그런 다음 질문의 예는 다음과 같습니다.
numb=1025
리틀 엔디안
LSB 00000001 00000100 00000000 00000000 MSB
그래서 << 10
될 수 10bit
에서 LSB MSB로 이동.
<< 10
Little Endian 형식의 단계별 비교 및 조작 :
MSB LSB
00000000 00000000 00000100 00000001 numb(1025)
00000000 00010000 00000100 00000000 << 10
LSB MSB
00000000 00000100 00010000 00000000 numb(1025) << 10, and put in a Little Endian Format
LSB MSB
00000001 00000100 00000000 00000000 numb(1205) in Little Endian format
00000010 00001000 00000000 00000000 << 1
00000100 00010000 00000000 00000000 << 2
00001000 00100000 00000000 00000000 << 3
00010000 01000000 00000000 00000000 << 4
00100000 10000000 00000000 00000000 << 5
01000000 00000000 00000001 00000000 << 6
10000000 00000000 00000010 00000000 << 7
00000000 00000001 00000100 00000000 << 8
00000000 00000010 00001000 00000000 << 9
00000000 00000100 00010000 00000000 << 10 (check this final result!)
와! OP가 설명한대로 예상 결과를 얻습니다!
OP가 예상 한 결과를 얻지 못한 문제는 다음과 같습니다.
-
그가 LSB에서 MSB로 이동하지 않은 것 같습니다.
-
리틀 엔디안 형식으로 비트를 옮길 때 다음을 인식해야합니다.
LSB 10000000 00000000 MSB << 1
있다
LSB 00000000 00000001 MSB
, 없다
LSB 01000000 00000000 MSB
각 개인마다 8bits
실제로 MSB 00000000 LSB
Big Endian 형식으로 작성하기 때문 입니다.
그래서 그것은
LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB
요약하면 :
-
비트 단위 연산은 blablablabla에서 추상화되었다고 말하지만, 비트 단위 연산을 직접 계산할 때 이진 형식을 종이에 적을 때 사용하는 엔디안을 여전히 알아야합니다. 또한 모든 연산자가 동일한 엔디안을 사용하도록해야합니다.
-
OP는 기대 한 결과를 얻지 못했습니다.