무엇이 유용하는 비트 or 연산자 코드 트릭해 개발자에 대해 알아?[마감]

StackOverflow https://stackoverflow.com/questions/1533131

문제

가본 적인 사용하는 비트 or 연산자,그러나 나는 거기에 몇 가지 작업이 있을 수행되었을 것이 더 효율적으로 수행됩니다.어떻게 해야"이동"와"또는 ing"당신이 도움이 문제를 해결을 더 효율적으로?

도움이 되었습니까?

해결책

유명한 사람을 참조하십시오 비트 twiddling 핵
곱하기/분할의 대부분은 불필요합니다. 컴파일러는 자동으로 수행되며 사람들을 혼동합니다.

그러나 하드웨어 또는 통신 프로토콜을 사용하는 경우 매우 유용한 'Check/Set/Toggle Bit N'유형 해킹이 있습니다.

다른 팁

문자열 (문자)에서 Bitwise 작업 사용

편지를 변환하십시오 소문자:

  • OR space =>에 의해 (x | ' ')
  • 글자가 이미 소문자 인 경우에도 결과는 항상 소문자입니다.
  • 예를 들어. ('a' | ' ') => 'a' ; ('A' | ' ') => 'a'

편지를 변환하십시오 대문자:

  • AND 밑줄에 의해 => (x & '_')
  • 결과는 이미 대문자 인 경우에도 항상 대문자입니다.
  • 예를 들어. ('a' & '_') => 'A' ; ('A' & '_') => 'A'

거꾸로 하다 편지의 경우 :

  • XOR space =>에 의해 (x ^ ' ')
  • 예를 들어. ('a' ^ ' ') => 'A' ; ('A' ^ ' ') => 'a'

편지 위치 알파벳에서 :

  • AND ~에 의해 chr(31)/binary('11111')/(hex('1F') => (x & "\x1F")
  • 결과는 1..26 범위이며 문자 케이스는 중요하지 않습니다.
  • 예를 들어. ('a' & "\x1F") => 1 ; ('B' & "\x1F") => 2

편지를 받으세요 위치 알파벳 (for 대문자 편지 만) :

  • AND ~에 의해 ? => (x & '?') 또는 XOR ~에 의해 @ => (x ^ '@')
  • 예를 들어. ('C' & '?') => 3 ; ('Z' ^ '@') => 26

편지를 받으세요 위치 알파벳 (for 소문자 편지 만) :

  • XOR Backtick/chr(96)/binary('1100000')/hex('60') => (x ^ '`')
  • 예를 들어. ('d' ^ '`') => 4 ; ('x' ^ '`') => 25

참고 : 영어 편지 이외의 다른 것을 사용하면 쓰레기 결과가 생성됩니다.


  • 정수에 대한 비트 타이어 작업 (int)

최대 정수를 얻으십시오

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

최소 정수를 얻으십시오

int minInt = 1 << 31;
int minInt = 1 << -1;

최대 길이를 얻으십시오

long maxLong = ((long)1 << 127) - 1;

2를 곱합니다

n << 1; // n*2

2로 나뉩니다

n >> 1; // n/2

2의 M-TH 전력을 곱한다

n << m;

2의 M-th Power로 나눈 값

n >> m;

홀수를 확인하십시오

(n & 1) == 1;

두 값을 교환합니다

a ^= b;
b ^= a;
a ^= b;

절대 가치를 얻으십시오

(n ^ (n >> 31)) - (n >> 31);

두 값의 최대를 얻으십시오

b & ((a-b) >> 31) | a & (~(a-b) >> 31);

두 값의 최소를 얻으십시오

a & ((a-b) >> 31) | b & (~(a-b) >> 31);

둘 다 동일한 부호가 있는지 확인하십시오

(x ^ y) >= 0;

2^n을 계산하십시오

2 << (n-1);

2의 계승 여부

n > 0 ? (n & (n - 1)) == 0 : false;

m에 대한 모듈로 2^n

m & (n - 1);

평균을 얻으십시오

(x + y) >> 1;
((x ^ y) >> 1) + (x & y);

N의 M-th 비트를 얻으십시오 (낮은 곳에서 최고로)

(n >> (m-1)) & 1;

n의 m-th 비트를 0으로 설정하십시오 (낮은 곳에서 높음)

n & ~(1 << (m-1));

n + 1

-~n

n -1

~-n

대비 번호를 얻으십시오

~n + 1;
(n ^ -1) + 1; 

if (x == a) x = b; if (x == b) x = a;

x = a ^ b ^ x;

내가 빈도로 사용한 세 가지만이 있습니다.

  1. 조금 설정하십시오 : a | = 1 << 비트;

  2. 비트를 비우십시오 : a & = ~ (1 << 비트);

  3. 비트가 설정되어 있음을 테스트합니다 : A & (1 << 비트);

문제 계산 : 아이디어, 알고리즘, 소스 코드, Jorg Arndt (PDF). 이 책에는 많은 것들이 포함되어 있습니다. http://www.hackersdelight.org/

오버플로가없는 평균

두 인수의 평균 (x + y)/2의 계산에 대한 루틴은 x와 y입니다.

static inline ulong average(ulong x, ulong y)
// Return floor( (x+y)/2 )
// Use: x+y == ((x&y)<<1) + (x^y)
// that is: sum == carries + sum_without_carries
{
    return (x & y) + ((x ^ y) >> 1);
}

할 수 있는 데이터 압축,예를 들어,컬렉션의 정수:

  • 는 정수 값에서 더 자주 이 컬렉션
  • 사용 짧은 비트 시퀀스를 나타내는 값에는 더 자주 나타납 (고 더 이상 비트 시퀀스를 나타내는 값이 나타나는 덜 자주)
  • 연결의 비트 시퀀스:그래서 예를 들어,첫 번째는 3 비트의 결과로 비트 스트림을 나타낼 수 있습니다 integer,다음 9 비트는 다른 정수,등등.

1) 2의 전력으로 나누거나 곱하는

foo >>= x; (2의 힘으로 나누기)

foo <<= x; (2의 힘으로 곱하기)

2) 스왑

x ^= y;
y = x ^ y;
x ^= y;

비트 타이어 운영자를 사용하여 거리 계산을 효율적으로 구현했습니다. 비트 스트링. 내 응용 프로그램에서 Bitstrings는 이산화 된 공간에서 위치를 나타 내기 위해 사용되었습니다 ( Octree, 관심이 있으시면 인코딩 Morton 주문). 그리드의 포인트가 특정 반경 내에 있는지 여부를 알기 위해 거리 계산이 필요했습니다.

세트 비트 계산, 가장 낮은/가장 높은 세트 비트를 찾기, nth-from-top/ottom set 비트를 찾는 것과 다른 사람들은 유용 할 수 있으며, 볼 가치가 있습니다. Bit-twiddling 해킹 대지.

즉, 이런 종류의 일은 일상적인 것이 중요하지 않습니다. 라이브러리를 갖는 데 유용하지만 가장 일반적인 용도는 간접적입니다 (예 : 비트셋 컨테이너 사용). 또한 이상적으로는 표준 라이브러리 기능입니다. 일부 플랫폼에서 전문화 된 CPU 명령어를 사용하여 많은 것이 더 잘 처리됩니다.

교대로 곱하거나 나누는 것은 멋진 것처럼 보이지만, 한 번에 필요한 유일한 것은 부울을 비트로 압축하는 것이 었습니다. 이를 위해서는 약간의 이동/반전이 필요합니다.

나는 숫자가 다음으로 가장 높은 2의 힘으로 반올림하는 기능을 원했기 때문에 여러 번 제기 된 Bit Twiddling 웹 사이트를 방문하여 다음을 생각해 냈습니다.

i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;

나는 그것을 a에 사용한다 size_t 유형. 아마도 서명 된 유형에서는 잘 작동하지 않을 것입니다. 다양한 크기의 유형을 가진 플랫폼에 대한 이식성이 걱정된다면 코드를 뿌립니다. #if SIZE_MAX >= (number) 적절한 장소에서의 지침.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top