비트 시프트(비트 시프트) 연산자란 무엇이며 어떻게 작동하나요?

틈틈이 C를 배우려고 노력해 왔는데, 다른 언어(C#, Java 등)도 같은 개념(그리고 종종 같은 연산자)을 가지고 있습니다 ...

제가 궁금한 것은 핵심 수준에서 비트 시프트(비트 시프트, 비트 시프트, 비트 시프트)가 무엇을 하고, 어떤 문제를 해결하는 데 도움이 될 수 있으며, 어떤 문제가 숨어 있습니까? 다시 말해, 비트 시프트의 모든 장점을 담은 완전 초보자 가이드입니다.

질문에 대한 의견 (4)
해결책

비트 이동 연산자는 이름에서 알 수 있듯이 비트 이동을 수행합니다. 비트를 이동합니다. 다음은 다양한 시프트 오퍼레이터에 대한 간략한(또는 그다지 간략하지 않은) 소개입니다.

연산자

  • `
해설 (22)

1바이트가 있다고 가정해 봅시다:

0110110

왼쪽 비트 시프트 하나만 적용하면 됩니다:

1101100

가장 왼쪽의 0이 바이트 밖으로 이동하고 바이트의 오른쪽 끝에 새로운 0이 추가되었습니다.

비트는 롤오버되지 않고 버려집니다. 즉, 1101100을 왼쪽으로 시프트했다가 오른쪽으로 시프트해도 동일한 결과를 다시 얻지 못합니다.

왼쪽으로 N을 이동하는 것은 2를 곱하는 것과 같습니다.

오른쪽으로 N만큼 이동하는 것은 ([ones; complement][1]를 사용하는 경우) 2N로 나눈 후 0으로 반올림하는 것과 같습니다.

비트 시프팅은 2의 거듭제곱으로 작업하는 경우 엄청나게 빠른 곱셈과 나눗셈에 사용할 수 있습니다. 거의 모든 저수준 그래픽 루틴은 비트 시프팅을 사용합니다.

예를 들어, 예전에는 게임에 모드 13h(320x200 256색)를 사용했습니다. 모드 13h에서는 비디오 메모리가 픽셀당 순차적으로 배치되었습니다. 즉, 픽셀의 위치를 계산하려면 다음과 같은 수식을 사용해야 했습니다:

memoryOffset = (row * 320) + column

당시에는 속도가 중요했기 때문에 비트 시프트를 사용하여 이 작업을 수행했습니다.

하지만 320은 2의 거듭제곱이 아니므로 이 문제를 해결하려면 더하면 320이 되는 2의 거듭제곱이 무엇인지 알아내야 합니다:

(row * 320) = (row * 256) + (row * 64)

이제 이를 좌변환으로 변환할 수 있습니다:


(row * 320) = (row 
해설 (6)

저급 프로그래밍 등 기본적인 하드웨어 또는 임베디드 운영, 비트 시프트 (shift), 비트 있다. 심지어 일부 이진 파일 포맷의 경우 읽기 위해 사양명세를 디바이스입니다 볼 수 있습니다, 단어 및 dword 바이트입니다 비사양 바이트입니다 비트필드스 정렬되고 줄바꿈할 분할하고 있는 다양한 값을 포함하고 있다. 이러한 비트 필드를 액세스하면 읽기 / 쓰기를 위한) 가 가장 일반적인 사용.

16 비트 그래픽 프로그래밍 픽셀입니다 표현되는 것은 단순한 실수 예는 다음과 같다.

  bit | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1  | 0 |
      |       Blue        |         Green         |       Red          |

이 값을 얻을 수 있는 녹색 emc. 할 것입니다.

 #define GREEN_MASK  0x7E0
 #define GREEN_OFFSET  5

 // Read green
 uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;
    • 설명

녹색 값을 얻기 위해 만 5, 10 시에 끝나며 오프셋할 시작하는 사용해야 합니다. (즉 6 비트 긴), 전체 16 비트 (bit) 가 있는 것은 오직 픽셀입니다 대해 적용했을 때 마스크 비트를 저희에게는힘과 관심이 모아지고 있다.

#define GREEN_MASK  0x7E0

0 000 011 111 100 000, 즉 적절한 마스크는 0x7e0 있는 binary) 은 2016년 자릿수를).

uint16_t green = (pixel & GREEN_MASK) ...;

마스크할 적용하십시오 및 연산자 (&), 사용할 수 있습니다.

uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;

39 를 적용하면, ll end up with you& 마스크를 한 이래 MSB () 은 16 비트 번호) 가 정말 11 비트 번호 11 비트. 실제로 우리 할 만 한 것, 긴 녹색 6 비트 배율입니다 사용하는, 즉 오른쪽 shift+ctrl (11) = 5 ~ 6) 로 사용을 5 오프셋된 (# define green_offset '5').

빠르게 변하는 일반적인 곱셈, 디비전 2 의 힘을 통해 약어입니다 사용하고 있다.

 i = y;  // i /= 2^y;
해설 (1)

약어입니다 마스킹과 &amp. # 바뀌고

흔히 사용되는 비트 등이 낮은 수준의 그래픽 프로그래밍. 예를 들어 특정 색상 값 인코딩되지 픽셀입니다 있는 32 비트 말을해야합니다.

 Pixel-Color Value in Hex:    B9B9B900
 Pixel-Color Value in Binary: 10111001  10111001  10111001  00000000

같은 것을 통해, 이진 값 레이블된 seabreeze 단면에는 대한 전반적인 이해가 어떤 색상 부품.

                                 Red     Green     Blue       Alpha
 Pixel-Color Value in Binary: 10111001  10111001  10111001  00000000

예를 들어 우리가 원하는 값을 # 39 의 말하도다 let& afaq 그린 이 픽셀입니다 색상. 로 간편하게 얻을 수 있는 가치 있는 우리는 마스킹과 및 이동.

우리의 마스크:

                  Red      Green      Blue      Alpha
 color :        10111001  10111001  10111001  00000000
 green_mask  :  00000000  11111111  00000000  00000000

 masked_color = color & green_mask

 masked_color:  00000000  10111001  00000000  00000000

&Amp 사용할 수 있는 논리 ',' 연산자입니다 값만 마스크는 1 유지됩니다. 마지막 한가지 이제 해야 하는 것이 올바른 의해 모든 x 16 비트 정수 값이 그 곳에서 오른쪽으로 옮기는 내려받습니다 (논리 오른쪽 shift) .

 green_value = masked_color >>> 16

우리는 양을 나타내는 et voil& 225, 정수 녹색으로 픽셀에는 색상:

 Pixels-Green Value in Hex:     000000B9
 Pixels-Green Value in Binary:  00000000 00000000 00000000 10111001 
 Pixels-Green Value in Decimal: 185

이것은 종종 사용되는 이미지 포맷은 jpg, png 'like' 인코딩 또는 디코딩 ',' '.'.

해설 (1)

한 가지 문제는 다음이 구현에 따라 달라진다는 점입니다(ANSI 표준에 따라):

char x = -1;
x >> 1;

x는 이제 127(01111111)이거나 여전히 -1(11111111)일 수 있습니다.

실제로는 보통 후자를 사용합니다.

해설 (3)

나는 데 쓰는 요령을 전용, 시험 / 시험을 볼 수도 있다.

n ':' n = 1. n = 1 ',' n&lt &lt. n/2 ':' n = 2. n = 1 ',' n&gt &gt. 3. 있는지 확인하는 n 은 2 의 거듭제곱 (1.2,4.8.): (n &amp, 체크 '! (n-1)) ' 4. , X&l 가져오는 sup&gt th&lt /sup>;; 다소 'n': 'n = (1 &lt <; x) ' 5. X 는 또는 홀수입니다 있는지 확인하는 것이다. 1 = 0 ',' x&amp (짝수) 6. 이 , , sup&gt th&lt n&l 전환하십시오 /sup>; 비트 x: 'x ^ (1&lt, &lt, n)'

해설 (3)

참고로, 비트 수를 shift+ctrl mod& # 39 는 Java 구현, 크기는 세로 x 소스.

예를 들면 다음과 같습니다.

(long) 4 >> 65

는 2. 모든 것을 기대할 수 있는 비트 오른쪽에 두는 쪽으로 65 배 아웃하지만 it& # 39 의 사실상 제로 아니하였으매 avamer 다음과 같다.

(long) 4 >> (65 % 64)

,,, 그리고 &gt &gt &lt 마찬가지입니다 &lt &gt &gt >;;). 다른 언어로 아웃해야 시도한 적이 없습니다.

해설 (1)

Python 에서 몇 가지 유용한 비트 운영 / 조작. Python 에서 @Ravi 구현됩니까 프라카시 대답.


# basic bit operations
# int to bin
print(bin(10))

# bin to int
print(int('1010',2))

# multiplying x with 2 .... x**2== x >1)

# modulo x with 2 .... x%2 == x&1
if 20&1==0:
    print("20 is a even number")

# check if n is power of 2 : check !(n & (n-1))
print(not(33 &(33-1)))

# getting xth bit of n : (n>>x)&1
print((10>>2)&1) # bin of 10==1010 and 2nd bit is 0

# toggle nth bit of x : x^(1
해설 (0)

Php 는 겨우 32 비트 버전의 Windows 플랫폼에서 사용할 수 있는 것을 염두에 두어야 합니다.

예를 들어, &lt &lt shift+ctrl 신앙이니라 있습니다. 또는 &gt >; 의해, 결과는 31 비트 이상의 오네스펙터블. 일반적으로 원래의 수가 될 수 있어 정말 까다로운 반환되었습니다, 대신 제로 버그.

물론 사용할 경우 64 비트 버전은 PHP (unix), 변화하는 이상 늘어난 63 비트임을 피해야 합니다 하지만, 예를 들어, MySQL 은 호환성 문제 때문에 64-비트 BIGINT 없어야 합니다.

업데이트: Php 7 에서 Windows, php 는 정수 전체 64bit 마침내 사용할 수 있다.

  • 정수가 플랫폼 종속적인, 비록 크기는 약 2 억 최대값인 는 일반적인 밸류급 (that& # 39 의 32 비트 서명됨). 일반적으로 약 64 비트 플랫폼으로 투명지에 최대값인 9e18 이전 windows, 여기서 it was always 32tb bit.* php 7 에서 제외)
해설 (0)