실제 프로젝트에서 비트 시프 팅을 사용해야했던 적이 있습니까?


83

실제 프로그래밍 프로젝트에서 비트 시프 팅 을 사용해야했던 적이 있습니까? 대부분의 (모두는 아니지만) 고급 언어에는 시프트 연산자가 있지만 실제로 언제 사용해야합니까?

답변:


58

나는 여전히 하드웨어에서 부동 소수점을 지원하지 않는 시스템에 대한 코드를 작성합니다. 이러한 시스템에서는 거의 모든 산술에 대해 비트 시프 팅이 필요합니다.

또한 해시를 생성하려면 시프트가 필요합니다. 다항식 산술 (CRC, 리드 솔로몬 코드가 주류 응용 프로그램 임) 또는 시프트도 사용합니다.

그러나 시프트는 편리하고 작가가 의도 한 바를 정확하게 표현하기 때문에 사용됩니다. 원하는 경우 곱셈을 사용하여 모든 비트 시프트를 에뮬레이트 할 수 있지만 작성하기가 더 어렵고 가독성이 떨어지고 때로는 느립니다.

컴파일러는 곱셈을 시프트로 줄일 수있는 경우를 감지합니다.


37

예, 많이 사용했습니다. 비트 트위들 링은 비트 마스크가 매우 일반적인 임베디드 하드웨어에서 중요합니다. 마지막 모든 성능이 필요할 때 게임 프로그래밍에서도 중요합니다.

편집 : 또한 색상 심도를 변경하거나 RGB <-> BGR을 변환하는 등 비트 맵을 조작하는 데 많이 사용합니다.


두 번째. 저는 임베디드 프로그래밍을 많이하는데 비트 시프 팅은 일반적인 작업입니다.
e.James

여기에서 RGB <-> BGR 변환.
Neil N

25
  • 열거 형에 대한 멋진 플래그 값 만들기 (수동으로 1, 2, 4를 입력하는 대신 ...)
  • 비트 필드에서 데이터 압축 풀기 (많은 네트워크 프로토콜에서 사용)
  • Z- 커브 횡단
  • 성능 해킹

그리고 나는 그들이 사용되는 많은 경우를 생각할 수 없습니다. 일반적으로 다른 방법입니다. 특정 문제가 있으며 비트 연산을 사용하면 최상의 결과를 얻을 수 있습니다 (일반적으로 성능-시간 및 / 또는 공간 측면에서).


예를 들어 두 개의 개별 값을 읽기 위해 Session을 읽고 잠그는 오버 헤드없이 ASP.net의 Session 상태 short에서 하나의 integer 필드에 두 개의 s 를 저장해야 할 수 있습니다 . 또한 세션에 두 값을 저장하는 메모리 오버 헤드가 저장됩니다.
David d C e Freitas 2011

15

내가 항상 사용하는 한 곳은 크로스 플랫폼 애플리케이션을 위해 정수의 엔디안을 전치 할 때입니다. 2D 그래픽을 블리 팅 할 때 (다른 비트 조작 연산자와 함께) 때때로 유용합니다.


둘째, EBCDIC 문자 집합에 대한 변환기를 작성합니다. 불행히도 이것은 고수준 언어에서 실제로 저수준 작업을 수행하지만 경우에 따라 필요합니다.
Michael Meadows

9

나는 그것들을 몇 번 사용했지만 거의 항상 바이너리 파일 형식을 구문 분석하는 데 사용되었습니다.


7

비트 시프트가 빠릅니다. 분할 및 모듈러스 연산이 수행되기 훨씬 전에 CPU 명령 세트에서 구현되었습니다. 우리 중 많은 사람들이 연필과 종이로는 간단하지만 CPU에서는 사용할 수없는 산술에 비트 시프트를 사용했습니다.

예를 들면 :

  • 나는 큰 합성물을 소인수로 분해하는 것과 관련된 프로젝트에 비트 시프트를 사용했습니다.
  • 또한 임의로 큰 정수의 제곱근과 세제곱근을 찾기 위해 비트 시프트를 사용했습니다.

큐브 또는 제곱근을 찾는 방법에 대한 예제를 게시 해 주시겠습니까? 나는 이것이 어떻게 될 수 있는지 조금 모르겠다.
Xsmael 2015 년

5

예, 여전히 필요합니다.

예를 들어 여기서는 직렬 포트 COMx를 통해 PLC와 통신하기위한 소프트웨어를 개발합니다. 한 바이트 내에서 비트를 처리 할 필요가 있으며, 왼쪽 / 오른쪽 시프트, 논리 연산자 OR, XOR, AND를 매일 사용합니다.

예를 들어, 바이트의 비트 3 (오른쪽에서 왼쪽)을 켜야한다고 가정 해 보겠습니다.

다음을 수행하는 것이 훨씬 더 효율적입니다.

Byte B;

B := B XOR 4;

대신에:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

문안 인사.


1
4가 비트 3 (오른쪽에서 왼쪽으로)과 관련된 이유를 추가 할 수 있습니다.
HCP

1
왜 s [5]입니까? S [2] 여야하지 않습니까?
IamIC 2014 년

1
B : = B XOR 4; 이 경우 특정 비트를 켜려면 단순히 OR이어야하지 않습니까? XOR은 토글에 사용되지 않습니까? stackoverflow.com/questions/47981/…
Hari

4

어셈블리 언어로 작성했을 때 내 코드는 비트 시프 팅과 마스킹으로 가득 차있었습니다.

C에서도 상당한 양을 보냈습니다.

자바 스크립트 나 서버 언어로는 많이하지 않았습니다.

아마도 가장 현대적인 용도는 1과 0으로 표시된 부울 값의 패킹 된 배열을 단계별로 살펴 보는 것입니다. 나는 항상 왼쪽으로 시프트하고 어셈블리에서 부호 비트를 확인했지만 더 높은 수준의 언어에서는 값과 비교합니다.

예를 들어, 8 비트가있는 경우 "if (a> 127) {...}"로 최상위 비트를 확인합니다. 그런 다음 왼쪽 시프트 (또는 2 곱하기)를 수행하고 127로 "and"를 수행 한 다음 (또는 마지막 비트가 설정된 경우 256을 빼고) 다시 수행합니다.


3

비트 맵의 ​​비트가 압축 된 이미지 압축 / 압축 해제에 많이 사용했습니다. http://en.wikipedia.org/wiki/Huffman_coding을 사용하면 압축되는 항목은 다양한 비트 수 (모두 바이트 정렬되지 않음)로 구성되므로 인코딩 또는 디코딩 할 때 비트 시프트해야합니다. .


3

예를 들어 C, C ++와 같은 언어의 암호화 방법 구현에서. 바이너리 파일, 압축 알고리즘 및 논리 목록 작업-비트 연산은 항상 좋습니다 =)


3

비트 시프 팅은 높은 수준의 프로그래밍 문제를 해결하지 못하지만 우리는 때때로 낮은 수준의 문제를 해결해야하며이를 수행하기 위해 C로 별도의 라이브러리를 작성할 필요가없는 것이 편리합니다. 그것이 가장 많이 사용되는 때입니다.

개인적으로 EBCDIC 문자 집합 변환기 용 인코더를 작성하는 데 사용했습니다 .


3

네, 있어요. 의심 할 수 있듯이, 장치 드라이버 개발과 같은 저수준 프로그래밍에서 발견 될 가능성이 가장 높습니다. 하지만 의료 기기에서 데이터를 수신하는 웹 서비스를 개발해야하는 C # 프로젝트에서 작업했습니다. 장치가 저장 한 모든 이진 데이터는 SOAP 패킷으로 인코딩되었지만 이진 데이터는 압축 및 인코딩되었습니다. 따라서 압축을 풀려면 많은 비트 조작을해야합니다. 또한 유용한 정보를 분석하기 위해 많은 비트 이동을 수행해야합니다. 예를 들어 장치 일련 번호는 두 번째 바이트의 아래쪽 절반 또는 이와 비슷한 것입니다. 또한 .NET (C #) 세계의 일부 사람들이 비트 마스킹 및 플래그 속성을 사용하는 것을 보았습니다. 개인적으로 그렇게하고 싶은 충동이 없었습니다.


3

네. 나는 이전에 암호화 알고리즘을 작성해야하는데 확실히 사용합니다.

상태를 추적하기 위해 정수 등을 사용할 때도 유용합니다.


3

숫자를 리틀 엔디안에서 빅 엔디안 형식으로 또는 그 반대로 변환 할 때


3

저는 컴퓨터 주변기기 제조업체에서 일합니다. 나는 거의 매일 비트 시프트를 사용하는 코드를 만났고 구현해야했다.


3

비트 시프 팅은 온라인 게임의 프로토콜을 해독하는 데 많이 사용됩니다. 프로토콜은 가능한 한 적은 대역폭을 사용하도록 설계되었으므로 서버의 플레이어 수, 이름 등을 int32s로 전송하는 대신 모든 정보가 가능한 한 적은 바이트로 압축됩니다. 요즘 대부분의 사람들이 광대역을 사용하는 경우에는 실제로 필요하지 않지만 원래 디자인되었을 때 사람들은 게임에 56k 모뎀을 사용했기 때문에 모든 비트가 중요합니다.

이에 대한 가장 두드러진 예는 Valve의 멀티 플레이어 게임, 특히 Counter-Strike, Counter-Strike Source입니다. Quake3 프로토콜도 동일하지만 Unreal은 그다지 슬림하지 않습니다.

다음은 예입니다 (.NET 1.1).

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

물론 이것을 실제 프로젝트로 보는지 아니면 취미로 보는지 (C #에서)는 당신에게 달려 있습니다.


2

고속 푸리에 변환 — FFT 및 Cooley-Tukey 기술은 비트 이동 연산을 사용해야합니다.


자신의 FFT 루틴을 롤링하십니까? tut-tut :) 저도 직접 해봤 음을 인정합니다-알고리즘을 깊이 이해하는 데 좋습니다.
Marty

2

주어진 숫자보다 크거나 같은 가장 가까운 2의 거듭 제곱을 찾으십시오.

1 << (int)(ceil(log2(given)))

임의의 텍스처 크기를 지원하지 않는 하드웨어의 텍스처링에 필요합니다.


1

예, MPEG2-2 전송 스트림 파서에서 사용했습니다. 더 쉬웠고 더 읽기 쉬웠습니다.


1

DVD 디스크의 .ifo 파일을 구문 분석하는 프로그램을 작성해야했습니다. 디스크에 얼마나 많은 타이틀, 챕터, 메뉴 등이 있는지 설명하는 파일입니다. 그들은 모든 크기와 정렬의 패킹 된 비트로 구성됩니다. 많은 바이너리 형식에 유사한 비트 이동이 필요하다고 생각합니다.


1

여러 플래그가 속성 매개 변수로 사용되었을 때 비트 연산자가 사용되는 것을 보았습니다. 예를 들어 숫자 4 = 10 0은 세 플래그 중 하나가 설정되었음을 의미합니다. 이것은 공용 API에는 좋지 않지만 비트 검사가 빠르기 때문에 특수한 경우 작업 속도를 높일 수 있습니다.


1

내가 쓴 모든 bitblt-er는 비트를 좌우로 밀 수있는 능력 없이는 완료 될 수 없었습니다.


1

나는 데이터 카드에 저장하기 위해 여러 플래그를 단일 바이트 / 문자로 포장하기 위해 게임에 사용했습니다. 잠금 해제 상태 등을 저장하는 것과 같은 것입니다. 요즘에는 그다지 요구 사항이 아니지만 작업을 절약 할 수 있습니다.


1

모니터의 EDID 데이터를 읽어야하는 임베디드 시스템 용 프로젝트에서 사용합니다. EDID의 일부 데이터는 다음과 같이 인코딩됩니다.

바이트 # 3 :
수평 블랭킹-하위 8 비트
바이트 # 4 :
하위 니블 : 수평 블랭킹-상위 4 비트
상위 니블 : 다른 것

1

예, Java와 C # 애플리케이션간에 바이너리 통신을 수행 할 때 하나는 빅 엔디안 바이트 순서이고 다른 하나는 리틀 엔디안입니다 (반드시이 순서는 아님). 다른 바이트 순서로 숫자를 읽을 수있는 InputStream 클래스를 만들었고 작업을 위해 바이트 시프트를 사용했습니다.

때로는 4 바이트의 long에 4 개의 short를 넣고 싶을 때도 byte shifting을 사용하는 경우가 있습니다. 몇 년 전에 그렇게 한 것 같아요 ...


1

또 다른 매우 일반적인 것은 바이트 의 높은 니블 을 추출 할 때 4 비트 시프트를 수행하는 것입니다.

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)

하드웨어로 직접 작업하고 임의의 비트 매핑을 사용하여 레지스터에서 직접 데이터를 가져 오는 경우 특히 그렇습니다.
Chris

0

비트 시프 팅은 "낮은 레벨"장비, eq 디지털 이더넷 -IO- 박스 또는 PLC와 통신 할 때도 필요합니다. 일반적으로 개별 입력 / 출력 값을 바이트로 압축합니다.



0

예, 항상. 32 비트 정수로 /에서 3 공간 좌표를 패킹하고 풀기위한 다음 매크로와 같습니다.

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        

0

한 번 (수년 전) Excel Oper 구조를 사용하여 Excel 스프레드 시트를 만든 프로젝트의 출력 루틴을 작성했습니다. 이것은 많은 양의 비트 트위들 링이 필요한 바이너리 파일 포먼트였습니다. 다음 링크는 Oper 구조 Safari Books의 특징을 제공 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.