C나 C++을 하다 보면은 shift 연산을 할 때가 많이 있습니다.
shift연산은 로우레벨 연산으로 비트를 왼쪽이나 오른쪽으로 밀어 내는 연산입니다.
shift 연산은 산술적으로 빠른 제곱근이 계산 됩니다. 왼쪽 shift 는 2^n 계산이 되고, 오른쪽 shift는 1/2^n이 되죠.
여기서 이야기 할 내용은.. 이 유용한 shift연산에 한가지 함정이 있다는 겁니다.
그것은 바로 32번 shift하는 것이지요. (32bit 운영체제 임을 가정 합니다.)
아래의 코드와 실행 결과를 확인 해 보겠습니다.
unsigned int x와 signed int y 두 개의 변수가 있는데.. 8번 shift하면은 x와 y의 값이 달라지게 됩니다. 이게 전형적인 shift 연산의 결과 입니다. ( 값이 다른 것은 굳이 설명 하지 않겠습니다. unsigned와 signed는 다른거 아시리라 가정 합니다.)
그다음에 밑에 보면은 32번 shift를 수행 합니다. 우리는 예상 하기로는.. x와 y를 왼쪽으로 32번 shift하면은 0이 나오길 기대 합니다. (y를 오른쪽으로 shift 하면 -1이 나오길 기대합니다.)
하지만 결과는 예상을 뛰어 넘습니다. 둘다 같은 값이 나오게 됩니다. 무슨 일일까요?
표준 C, C++ 규약인 ISO/IEC 14882:2003 5.8 섹션에서 다음과 같이 이야기 하고 있습니다.
5.8 Shift operators
1 The shift operators << and >> group left-to-right.
shift-expression: additive-expression
shift-expression << additive-expression shift-expression >> additive-expression
[expr.shift]
The operands shall be of integral or enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
2 The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise. [Note: the constants ULONG_MAX and UINT_MAX are defined in the header <climits>). ]
3 The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 divided by the quantity 2 raised to the power E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.
오른쪽 operand가 음수 이거나 왼쪽 피연산자 데이터 타입의 비트 길이보다 크게 되면은 Undefined 로 정의 되어 있습니다.
제가 이걸 알게 된 경우는 비트 마스크를 사용 하다 알게 되었는데, 컴파일러는 표준대로 undefined로 처리를 해버려 버그를 유발 하게 됩니다.
저처럼 마스크 연산을 위해 32번 shift를 해야 하는 경우가 발생 하게 되면은, 아무 생각 없이 위와 같이 하면 안됩니다. 16번씩 두번 shift를 하던가 해야 됩니다.
다음 그림은 제가 원하는 결과를 수행 하기 위해 수정 한 코드 입니다.
결과를 보면 알 수 있듯이, x는 0이 나오고 y는 오른쪽 shift일땐 -1이 나오고 왼쪽 shift는 0이 나왔습니다.
shift연산은 굉장히 유용한 연산이고 자주 사용 되는 연산이나, 위와 같은 특수한 경우를 보통 모르고 있기 때문에 유의 하여야 됩니다.
이 포스트를 올리는 이유중 하나는 사실 많은 우리나라 사람들은 이메일 클라이언트를 잘 사용 하지 않는 다는 것이 안타까워서 이다.. (일반 유저들을 이야기 하고 있는 것임. 회사에서는 업무를 이메일을 주로 이용해서 커뮤니케이션을 하기 때문에 아웃룩을 많이들 사용 한다.)
미국이나 다른 나라는 이메일이 주류로 사용 되고 있는데 반해 이메일 자체를 별로 잘 사용 하지 않는 것도 있다.
이것은 우리나라는 문자메세지의 발달로 인해 간단하고 쉽게 문자 메세지를 보낼 수 있었기 때문으로 생각 된다. 사실 문자메세지 서비스는 우리나라가 다른 나라보다 훨씬 먼저 시작 된 서비스 이다.
문자 메세지는 항상 휴대하는 휴대폰으로 바로 알림이 오는데 이메일은 웹으로 접속을 하거나 컴퓨터가 있어야 확인이 되기 때문에 잘 사용 되지 않는 것도 이유중 하나다.
하지만 요즘은 인터넷이 어느 곳에서든 잘 되고 컴퓨터를 많이 사용 하는 세상이 되어서 이메일이 다시 각광 받으리라 생각 된다.
이메일은 사진이나 동영상, 텍스트등 자유롭게 입력할 수가 있고 필요에 따라 검색도 할 수 있고 공짜이기 때문에 잘만 사용 하면 유용하게 사용 할 수가 있다.
웹에서 해도 되지만 검색과 이메일을 내 컴퓨터에서 보관하고 관리하고 싶은 사람들은 이메일 클라이언트를 사용 하길 권해 본다.
여기에서는 썬더버드 3.0.4와 구글의 Gmail을 이용하여 가정에서 직접 이메일을 관리 하는 방법을 설명 하겠다.
지메일 계정이 생성 되면 가장 먼저 할 일이 있는데 그것은 IMAP을 사용 가능으로 설정 하는 것이다.
이메일은 서버를 통해서 오고 가게 되는데 보내는 서버가 있고 받는 서버가 있다. 받는 서버는 IMAP으로 설정 되어 있는데 Gmail에서 설정을 켜야 클라이언트가 사용 가능 하므로 미리 작업을 수행 하자.
지메일에 로그인 하면은 우측 상단에 환경 설정이 있다. 여길 클릭 한다.
환경 설정에 들어가면 탭 메뉴 중에 전달 및 POP/IMAP 메뉴가 있는데 클릭 한다.
여기서 우리는 IMAP을 사용 하는 걸로 한다. 클라이언트 설정 관련 도움말도 있으니 참고 하면 좋다.
이제 썬더버드를 다운로드 받아야 된다. 다음의 링크 또는 사이트에서 다운로드 할 수가 있다.
2. 추가 포함 디렉터리에 압축을 풀어둔 OpenGL ES SDK의 include 폴더를 연결 한다.
3. OpenGL ES 라이브러리 파일의 링크 속성을 설정 하기 위해 링커 탭을 연다.
일반탭을 누르면 다음과 같이 나온다.
추가 라이브러리 디렉터리에 압축을 푼 SDK 폴더에 bin 폴더에 CPU에 맞는 폴더를 선택 ( 여기서는 ARM ) 한 다음 Debug 버전이면 Debug, Release 버전이면 Release를 선택 한다.
4. 다음엔 링커에 입력 탭을 눌러서 OpenGL ES 라이브러리를 입력 한다.
입력할 라이브러리 파일은 2개 이며 각각 codegen.lib, libGLES_CM.lib 파일이다.
5. 프로젝트 속성 설정은 이걸로 끝난다. 사실 include 폴더나 lib폴더는 visual studio 도구에서 프로젝트 및 솔루션 탭
에서 추가 하면 보통 다 되는데 OpenGL ES SDK를 그렇게 하니까 include에 있는 ug.h를 인식 하지 못한다. (
이유는 아직 모름 ) 그래서 귀찮지만 모든 프로젝트 마다 일일이 프로젝트 속성에서 추가 하는 수고를 해야 할 거 같다.
6. 다음으로는 에뮬레이터에 대한 추가 작업이다.
먼저 visual studio 도구에서 장치 에뮬레이터 관리자를 실행 한다.
7. 장치 에뮬레이터 관리자에서 사용할 에뮬레이터를 찾은 다음 우버튼 클릭을 하면 다음과 같은 팝업 윈도우가 뜬다. ( 여기서는 6.1.4 480 X 800 에뮬레이터를 사용 한다. T*OMNIA 에뮬레이터 )
연결을 선택해 에뮬레이터를 실행 한다.
8. 미리 설치한 Microsoft ActiveSync를 실행 한다음 연결 설정을 연다.
9. 그림과 같이 연결 허용에 DMA를 선택 하고 확인 버튼을 클릭 한다.
10. 장치 에뮬레이터 관리자를 실행한 다음, 실행중인 에뮬레이터 ( 지금은 6.1.4 480 X 800 에뮬레이터 )에서 우클릭을 한 다음 크레들에 놓기 를 실행 하면 ActiveSync에 연결 된다.
11. 취소 버튼을 눌러 마법사를 종료 한다.
12. ActiveSync에서 탐색 버튼을 눌러 에뮬레이터의 파일 시스템에 접근 한다.
13. Mobile 장치 폴더를 선택 해서 들어간다.
14. 첨에는 windows 폴더가 숨겨져 있어서 보이지 않는다. 폴더 옵션에서 숨겨진 폴더 보여주기를 선택해 숨겨진 windows 폴더에 접근 한다.
다음과 같이 숨겨진 폴더와 파일들이 보여진다. windows 폴더에 들어간다.
15. 압축을 푼 OpenGL ES SDK 폴더에 bin/arm/Debug or Release 폴더 안에 있는 libGLES_CM.dll 파일을 복사 해서 붙여 넣는다. ( 만약 프로그램이 Debug 버전이면 Debug 폴더를, Release 버전이면 Release 폴더에 있는 dll 파일을 복사 한다. )
16. 이제 에뮬레이터의 상태를 저장 하고 난 다음 종료 하면 된다. 만약 저장 하지 않거나 저장된 상태를 제거 하게 되면
windows 폴더에 있는 libGLES_CM.dll 파일이 지워지게 되어 다시 작업해야 하니 초기 부팅 상태를 저장 해 놓고
사용 하면 된다.
17. 이제 모든 환경 설정은 끝났다. 예제 프로그램을 실행 해 보자. 그러면 방금 설정한 에뮬레이터의 화면에 까만 배경에 큐브가 보일 것이다. 네비게이션 키를 누르면 큐브가 회전 한다.
OpenSSL은 SSL과 TLS 프로토콜을 구현해 놓은 오픈 소스를 뜻한다. SSL이란 Secure Socket Layer의 약자로 브라우저와 웹 서버 사이의 보안을 위해 만들어 졌다.
소스는 여기에서 다운로드 받을 수 있으며 바이너리 형태로 제공 하지 않고 소스를 제공 한다.
( Download! )
그렇기 때문에 소스를 컴파일도 하고 링크도 걸어야 사용이 가능 하다. 압축을 풀면 INSTALL이란 이름으로 되어 있는 문서파일이 하나 있다. OpenSSL을 설치 하는 방법을 기술 해 놓았다.
이 내용은 openssl-0.9.8k 버전을 기준으로 작성 되었음을 알린다.
기본적으로 유닉스 플랫폼에 설치 하는 것을 기술 하였다.
DOS나 Windows, Mac OS X 이전 버전은 각각 따로 기술된 문서를 참조 해야 한다.
설치를 위해서는 다음의 것들이 필요 하다.
* make
* Perl 5
* an ANSI C compiler
* a development environment in form of development libraries and C header files
* a supported Unix operating system
만약 위와 같이 했을 때 실패 메세지가 나온다면, 다음에 나오는 상세 설치 섹션을 참고 하자.
OpenSSL을 설치 하면 관행 적으로 /usr/local/ssl 위치에 설치가 된다. 만약 임의의 위치에 설치 하고 싶다면 config 옵션을 다음과 같이 주자. $ ./config --prefix=/usr/local --openssldir=/usr/local/openssl
다음은 build config 옵션에 대한 설명 이다.
--prefix=DIR : DIR/bin, DIR/lib, DIR/include/openssl 위치에 설치 한다. OpenSSL에서 사용하는 Configuration 파일은 DIR/ssl에 위치 하거나 --openssldir에 명세 해놓은 디렉토리에 존재 하게 된다.
--openssldir=DIR: OpenSSL 파일을 위한 디렉토리 이다. 만약 미리 명세 하지 않으면 라이브러리 파일과 바이너리 파일도 역시 그곳에 설치 된다.
no-threads : 다중 스레드 (Multi-Thread)를 지원하는 어플리케이션에 사용 한다면 적용 하면 안된다.
threads : 다중 스레드 (Multi-Thread)를 사용하는 어플리케이션이면 적용 해야 한다. 이 옵션은 일반적으로 시스템에 의존적인 옵션의 증가를 요구 할 것이다. 다음의 " 멀티 스레딩에 대한 기록 " 섹션을 참고 하라.
no-zlib : zlib의 압축과 해제를 사용 한다면 적용 하면 안된다.
zlib : zlib의 압축과 해제를 사용 한다면 적용 한다.
zlib-dynamic : zlib 옵션과 비슷 하다. 하지만 zlib가 필요할 때 OpenSSL이 동적으로 zlib 라이브러리를 로드 한다. 이것은 공유 라이브러리 로딩을 지원 하는 시스템에서만 지원 된다. 이 옵션은 기본 선택 이다.
no-shared : 공유 라이브러리를 생성 할때 적용 하면 안된다.
shared : 보통의 정적 라이브러리에 더하여, 플랫폼에 공유 라이브러리를 생성 한다. 다음의 " 공유 라이브러리에 대한 기록 " 참조 하라.
no-asm : 어셈블리 코드를 지원 하지 않는 옵션 이다.
386 : 80386 명령어 셋만 사용 하는 옵션 이다. ( 기본적으로 x86코드는 더 많은 효과가 있지만 최소한 486은 필요로 한다.)
Note : 다른 특수한 Configuration CPU에는 컴파일러 플래그들을 사용 하라.
e.g : " -m32 "는 x86 코드를 x64시스템에 빌드 시킨다.