Web/PHP
비트연산 응용
aucd29
2013. 9. 26. 21:43
험험..어제 술먹은게 덜깼는지 머리 아프군요.알람 맞쳐 놓고 자는걸 깜박해서 늦잠자고 부랴부랴 일어나서 회사 출근하는데 그만 졸다가 종착역까지 가고..-_-;; 암튼 오늘은 쉣!트! 한 날입니다.
기분전환겸 비트연산을 응용한 기법? -_-;; 을 남기고자 합니다.
이건 이미 여러번 다른 님들께서 올려주신 팁이구요.다른님들이 쓰신 글들도 같이 읽어 보세요.C언어에 익숙하신분이나 비트연산이 지겨우신분은 안읽어도 되는 내용입니다.-_-;;ㅋ
1byte = 000000 = 8개의 비트로 구성된 데이터 단위 입니다.
1byte = 비트 8개
2byte = 비트 16개
4byte = 비트 32개
8byte = 비트 64개
암튼 이에 대해서 더 자세히 알고 싶은 분은 구글링 하세요.
하나의 비트가 표현할 수 있는 상태는 0 아니면 1 입니다.0 아니면 1이기 때문에 boolean형 데이터를 세팅하는데에는 아주 좋습니다.즉 8byte형 변수에다가 64개의 true or false의 상태를 세팅할 수 있다는 얘기입니다.와우~ 그럼 이게 무슨 의미가 있느냐는 알아 두는게 좋겠죠?
만약에 어떤 사용자가 어떤번호를 골랐고 번호를 고른 총 횟수가 몇번인지 구하는 예제를 보통은 이렇게 작성합니다.
// 번호는 5개로 고정적이라고 하자.
// 1은 선택함,0은 선택안함
$UserNum=array(1,0,1,0,1,0);
$UserNumCount=array_sum($UserNum);
print $UserNumCount."번 선택함<br>\n";
$Size=count($UserNum);
for($i=0;$i<$Size;++$i){
print (($UserNum[$i]==1) ? ($i+1)."번 선택됨<br>\n" : "");
}
이정도면 괜찮죠?근데 잘생각해 보면 php의 int형 크기는 32비트 즉 4바이트(32비트 환경에서)입니다.한마디로 저 $UserNum 이라는 변수는 4*count($UserNum) 만큼 변수공간을 차지 하게 되는거니깐 위의 예제에서는 상태를 세팅하기 위해서 무려 20바이트를 차지하게 되는군요.그깟 true or false의 데이터를 저장하기 위해서 20바이트를 차지한단 말입니까?
이때 비트 연산을 응용하면 훨씬 적은 저장공간을 차지하게 됩니다.비트연산으로 저장된 값인지 알지 못하면 그 값이 무엇을 의미하는지 그냥 숫자로 봐서는 첫눈에 알기도 힘듭니다.-_-;;대략 효과 좋음.
그럼 저걸 똑같이 비트 연산을 응용한 버전으로 바꿔보도록 하겠습니다.
function BitSum($Var,$St,$Ed){
$Sum=0;
for($St;$St<=$Ed;++$St){
$Sum+=(($Var&(1<<$St))>>$St);
}
return $Sum;
}
$UserNum=((1<<1)|(1<<3)|(1<<5)); // 101010 대략 이렇게 -_-;;편의상 비트 6개로..
$UserNumCount=BitSum($UserNum,1,5);
print $UserNumCount."번 선택함<br>\n";
for($i=1;$i<=5;++$i){
print ((($UserNum&(1<<$i))!=0) ? ($i)."번 선택됨<br>\n" : "");
}
자 출력결과를 보면 알 수 있듯이 똑같습니다.번호가 세팅된 순서를 더 자세히 보여드리면 아래와 같습니다.
초기 상태
000001
1번 세팅
000010 // 000001 을 왼쪽으로 1번 쉬프트
3번 세팅
001000 // 000001 을 왼쪽으로 3번 쉬프트
5번 세팅
100000 // 000001 을 왼쪽으로 5번 쉬프트
// 이걸 몽땅 or(|) 연산을 해주면 세팅된 값이 나옵니다.
101010 // 이렇게 나옵니다.
이제 BitSum에 대해서 알아 보겠습니다.함수 내부를 보면 (($Var&(1<<$St))>>$St) 이게 좀 난해하게 보일 수도 있는데 -_-;; 연산자 우선순위가 헷갈리면 무조건 ()로 묶어 주는게 좋습니다.
// 함수의 첫번째 인자는 값이 세팅된 변수
// 두번째 인자는 시작 비트 오프셋
// 세번재 인자는 끝나는 비트 오프셋
(($Var&(1<<$St))>>$St)
// $Var 에는 101010 이 세팅 되어 있죠? 일단은 $St 가 1일때 의 값이 어떻게 나오는지 보겠습니다.
((101010&(000010))>>1)
// 이렇게 나오는데 이걸 다시 풀어보면
(000010)>>1
// 결국은 1 이라는 숫자가 나오게 되고 이런식으로 $St 에서 $Ed 까지 반복하면서 모두 더해주면 총 선택한 횟수가 나오게 되는겁니다.
이제 마직막으로 어떤 숫자가 선택되었는지 알아볼 차례네요 ^^;이거 영 허접스러운거 같아서 죄송.
for($i=1;$i<=5;++$i){
print ((($UserNum&(1<<$i))!=0) ? ($i)."번 선택됨<br>\n" : "");
}
이건데 이것도 BitSum함수 내부에 있는것과 비슷합니다.시작 오프셋에서 끝나는 오프셋까지 루프를 돌면서 선택된 값들을 찾아내는 겁니다.이건 의외로 간단합니다.값이 셋팅되었다면 2 이상이 되기때문에 그것만 찾아서 뿌려주면 되는겁니다.ㅋ -_-;
여러개의 바이트로 단순히 true or false의 데이터를 세팅하는 데이터 베이스 테이블에서는 아주 유용하게 사용될수도 있고 속도 향상도 볼 수 있습니다.
KIN
기분전환겸 비트연산을 응용한 기법? -_-;; 을 남기고자 합니다.
이건 이미 여러번 다른 님들께서 올려주신 팁이구요.다른님들이 쓰신 글들도 같이 읽어 보세요.C언어에 익숙하신분이나 비트연산이 지겨우신분은 안읽어도 되는 내용입니다.-_-;;ㅋ
1byte = 000000 = 8개의 비트로 구성된 데이터 단위 입니다.
1byte = 비트 8개
2byte = 비트 16개
4byte = 비트 32개
8byte = 비트 64개
암튼 이에 대해서 더 자세히 알고 싶은 분은 구글링 하세요.
하나의 비트가 표현할 수 있는 상태는 0 아니면 1 입니다.0 아니면 1이기 때문에 boolean형 데이터를 세팅하는데에는 아주 좋습니다.즉 8byte형 변수에다가 64개의 true or false의 상태를 세팅할 수 있다는 얘기입니다.와우~ 그럼 이게 무슨 의미가 있느냐는 알아 두는게 좋겠죠?
만약에 어떤 사용자가 어떤번호를 골랐고 번호를 고른 총 횟수가 몇번인지 구하는 예제를 보통은 이렇게 작성합니다.
// 번호는 5개로 고정적이라고 하자.
// 1은 선택함,0은 선택안함
$UserNum=array(1,0,1,0,1,0);
$UserNumCount=array_sum($UserNum);
print $UserNumCount."번 선택함<br>\n";
$Size=count($UserNum);
for($i=0;$i<$Size;++$i){
print (($UserNum[$i]==1) ? ($i+1)."번 선택됨<br>\n" : "");
}
이정도면 괜찮죠?근데 잘생각해 보면 php의 int형 크기는 32비트 즉 4바이트(32비트 환경에서)입니다.한마디로 저 $UserNum 이라는 변수는 4*count($UserNum) 만큼 변수공간을 차지 하게 되는거니깐 위의 예제에서는 상태를 세팅하기 위해서 무려 20바이트를 차지하게 되는군요.그깟 true or false의 데이터를 저장하기 위해서 20바이트를 차지한단 말입니까?
이때 비트 연산을 응용하면 훨씬 적은 저장공간을 차지하게 됩니다.비트연산으로 저장된 값인지 알지 못하면 그 값이 무엇을 의미하는지 그냥 숫자로 봐서는 첫눈에 알기도 힘듭니다.-_-;;대략 효과 좋음.
그럼 저걸 똑같이 비트 연산을 응용한 버전으로 바꿔보도록 하겠습니다.
function BitSum($Var,$St,$Ed){
$Sum=0;
for($St;$St<=$Ed;++$St){
$Sum+=(($Var&(1<<$St))>>$St);
}
return $Sum;
}
$UserNum=((1<<1)|(1<<3)|(1<<5)); // 101010 대략 이렇게 -_-;;편의상 비트 6개로..
$UserNumCount=BitSum($UserNum,1,5);
print $UserNumCount."번 선택함<br>\n";
for($i=1;$i<=5;++$i){
print ((($UserNum&(1<<$i))!=0) ? ($i)."번 선택됨<br>\n" : "");
}
자 출력결과를 보면 알 수 있듯이 똑같습니다.번호가 세팅된 순서를 더 자세히 보여드리면 아래와 같습니다.
초기 상태
000001
1번 세팅
000010 // 000001 을 왼쪽으로 1번 쉬프트
3번 세팅
001000 // 000001 을 왼쪽으로 3번 쉬프트
5번 세팅
100000 // 000001 을 왼쪽으로 5번 쉬프트
// 이걸 몽땅 or(|) 연산을 해주면 세팅된 값이 나옵니다.
101010 // 이렇게 나옵니다.
이제 BitSum에 대해서 알아 보겠습니다.함수 내부를 보면 (($Var&(1<<$St))>>$St) 이게 좀 난해하게 보일 수도 있는데 -_-;; 연산자 우선순위가 헷갈리면 무조건 ()로 묶어 주는게 좋습니다.
// 함수의 첫번째 인자는 값이 세팅된 변수
// 두번째 인자는 시작 비트 오프셋
// 세번재 인자는 끝나는 비트 오프셋
(($Var&(1<<$St))>>$St)
// $Var 에는 101010 이 세팅 되어 있죠? 일단은 $St 가 1일때 의 값이 어떻게 나오는지 보겠습니다.
((101010&(000010))>>1)
// 이렇게 나오는데 이걸 다시 풀어보면
(000010)>>1
// 결국은 1 이라는 숫자가 나오게 되고 이런식으로 $St 에서 $Ed 까지 반복하면서 모두 더해주면 총 선택한 횟수가 나오게 되는겁니다.
이제 마직막으로 어떤 숫자가 선택되었는지 알아볼 차례네요 ^^;이거 영 허접스러운거 같아서 죄송.
for($i=1;$i<=5;++$i){
print ((($UserNum&(1<<$i))!=0) ? ($i)."번 선택됨<br>\n" : "");
}
이건데 이것도 BitSum함수 내부에 있는것과 비슷합니다.시작 오프셋에서 끝나는 오프셋까지 루프를 돌면서 선택된 값들을 찾아내는 겁니다.이건 의외로 간단합니다.값이 셋팅되었다면 2 이상이 되기때문에 그것만 찾아서 뿌려주면 되는겁니다.ㅋ -_-;
여러개의 바이트로 단순히 true or false의 데이터를 세팅하는 데이터 베이스 테이블에서는 아주 유용하게 사용될수도 있고 속도 향상도 볼 수 있습니다.
KIN