무엇이 유용하는 비트 or 연산자 코드 트릭해 개발자에 대해 알아?[마감]
-
20-09-2019 - |
문제
가본 적인 사용하는 비트 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;
내가 빈도로 사용한 세 가지만이 있습니다.
조금 설정하십시오 : a | = 1 << 비트;
비트를 비우십시오 : a & = ~ (1 << 비트);
비트가 설정되어 있음을 테스트합니다 : 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;
세트 비트 계산, 가장 낮은/가장 높은 세트 비트를 찾기, 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)
적절한 장소에서의 지침.