실제 프로그래밍 프로젝트에서 비트 시프 팅 을 사용해야했던 적이 있습니까? 대부분의 (모두는 아니지만) 고급 언어에는 시프트 연산자가 있지만 실제로 언제 사용해야합니까?
실제 프로그래밍 프로젝트에서 비트 시프 팅 을 사용해야했던 적이 있습니까? 대부분의 (모두는 아니지만) 고급 언어에는 시프트 연산자가 있지만 실제로 언제 사용해야합니까?
답변:
나는 여전히 하드웨어에서 부동 소수점을 지원하지 않는 시스템에 대한 코드를 작성합니다. 이러한 시스템에서는 거의 모든 산술에 대해 비트 시프 팅이 필요합니다.
또한 해시를 생성하려면 시프트가 필요합니다. 다항식 산술 (CRC, 리드 솔로몬 코드가 주류 응용 프로그램 임) 또는 시프트도 사용합니다.
그러나 시프트는 편리하고 작가가 의도 한 바를 정확하게 표현하기 때문에 사용됩니다. 원하는 경우 곱셈을 사용하여 모든 비트 시프트를 에뮬레이트 할 수 있지만 작성하기가 더 어렵고 가독성이 떨어지고 때로는 느립니다.
컴파일러는 곱셈을 시프트로 줄일 수있는 경우를 감지합니다.
그리고 나는 그들이 사용되는 많은 경우를 생각할 수 없습니다. 일반적으로 다른 방법입니다. 특정 문제가 있으며 비트 연산을 사용하면 최상의 결과를 얻을 수 있습니다 (일반적으로 성능-시간 및 / 또는 공간 측면에서).
short
에서 하나의 int
eger 필드에 두 개의 s 를 저장해야 할 수 있습니다 . 또한 세션에 두 값을 저장하는 메모리 오버 헤드가 저장됩니다.
내가 항상 사용하는 한 곳은 크로스 플랫폼 애플리케이션을 위해 정수의 엔디안을 전치 할 때입니다. 2D 그래픽을 블리 팅 할 때 (다른 비트 조작 연산자와 함께) 때때로 유용합니다.
비트 시프트가 빠릅니다. 분할 및 모듈러스 연산이 수행되기 훨씬 전에 CPU 명령 세트에서 구현되었습니다. 우리 중 많은 사람들이 연필과 종이로는 간단하지만 CPU에서는 사용할 수없는 산술에 비트 시프트를 사용했습니다.
예를 들면 :
예, 여전히 필요합니다.
예를 들어 여기서는 직렬 포트 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);
문안 인사.
어셈블리 언어로 작성했을 때 내 코드는 비트 시프 팅과 마스킹으로 가득 차있었습니다.
C에서도 상당한 양을 보냈습니다.
자바 스크립트 나 서버 언어로는 많이하지 않았습니다.
아마도 가장 현대적인 용도는 1과 0으로 표시된 부울 값의 패킹 된 배열을 단계별로 살펴 보는 것입니다. 나는 항상 왼쪽으로 시프트하고 어셈블리에서 부호 비트를 확인했지만 더 높은 수준의 언어에서는 값과 비교합니다.
예를 들어, 8 비트가있는 경우 "if (a> 127) {...}"로 최상위 비트를 확인합니다. 그런 다음 왼쪽 시프트 (또는 2 곱하기)를 수행하고 127로 "and"를 수행 한 다음 (또는 마지막 비트가 설정된 경우 256을 빼고) 다시 수행합니다.
비트 맵의 비트가 압축 된 이미지 압축 / 압축 해제에 많이 사용했습니다. http://en.wikipedia.org/wiki/Huffman_coding을 사용하면 압축되는 항목은 다양한 비트 수 (모두 바이트 정렬되지 않음)로 구성되므로 인코딩 또는 디코딩 할 때 비트 시프트해야합니다. .
네, 있어요. 의심 할 수 있듯이, 장치 드라이버 개발과 같은 저수준 프로그래밍에서 발견 될 가능성이 가장 높습니다. 하지만 의료 기기에서 데이터를 수신하는 웹 서비스를 개발해야하는 C # 프로젝트에서 작업했습니다. 장치가 저장 한 모든 이진 데이터는 SOAP 패킷으로 인코딩되었지만 이진 데이터는 압축 및 인코딩되었습니다. 따라서 압축을 풀려면 많은 비트 조작을해야합니다. 또한 유용한 정보를 분석하기 위해 많은 비트 이동을 수행해야합니다. 예를 들어 장치 일련 번호는 두 번째 바이트의 아래쪽 절반 또는 이와 비슷한 것입니다. 또한 .NET (C #) 세계의 일부 사람들이 비트 마스킹 및 플래그 속성을 사용하는 것을 보았습니다. 개인적으로 그렇게하고 싶은 충동이 없었습니다.
숫자를 리틀 엔디안에서 빅 엔디안 형식으로 또는 그 반대로 변환 할 때
비트 시프 팅은 온라인 게임의 프로토콜을 해독하는 데 많이 사용됩니다. 프로토콜은 가능한 한 적은 대역폭을 사용하도록 설계되었으므로 서버의 플레이어 수, 이름 등을 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 #에서)는 당신에게 달려 있습니다.
고속 푸리에 변환 — FFT 및 Cooley-Tukey 기술은 비트 이동 연산을 사용해야합니다.
예, 비트 시프 팅은 항상 로우 레벨 임베디드 소프트웨어에서 사용되고 있습니다. 또한 매우 빠른 수학 연산을 수행하는 거의 마술로 사용할 수 있습니다.
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
한 번 (수년 전) Excel Oper 구조를 사용하여 Excel 스프레드 시트를 만든 프로젝트의 출력 루틴을 작성했습니다. 이것은 많은 양의 비트 트위들 링이 필요한 바이너리 파일 포먼트였습니다. 다음 링크는 Oper 구조 Safari Books의 특징을 제공 합니다.