2. 목차
◦ 컴퓨터 시스템 2장 : 정보의 표현과 처리
◦ 개요
◦ 정보의 저장 //2.1장
◦ 정수의 표시 //2.2장
◦ 정수의 산술연산 //2.3장
◦ 부동소수점 //2.4장
◦ 과제
◦ 직접 손으로 계산해보기
◦ 풀이
◦ 부록
◦ 참고 사이트
3. 개요
◦ 컴퓨터에서의 표현
◦ 이진수를 이용
◦ 쉽게 표현, 저장, 전송이 가능
◦ 펀치카드에 구멍이 뚫렸는지 막혔는지
◦ 전선에 높은 전압이 걸리는지 낮은 전압이 걸리는지
◦ 자기장이 시계 방향인지 반 시계 방향인지
◦ 하나의 비트만으로는 의미가 없음
◦ 비트 패턴에 의미를 부여하도록 특정 해석 방법을 적용하면 의미가 있음
◦ 앞으로 비트 패턴의 인코딩에 대해 알아볼 것임
◦ 정수
◦ 비부호형 인코딩(unsigned)
◦ 부호형 인코딩(signed)
◦ 2의 보수
◦ 소수
◦ 부동 소수점 인코딩
5. 정보의 저장
◦ 메모리
◦ 대부분의 컴퓨터에서 메모리 주소 지정이 가능한 최소 단위는 1바이트
◦ 비트단위로 접근하지 않고 최소 1바이트 단위로 접근한다.
◦ 프로그램은 메모리를 가상 메모리라는 거대한 바이트의 배열로 취급
◦ 주소를 인덱스삼아 접근
◦ 모든 가능한 주소의 집합을 가상 주소공간이라 함
◦ Ex) 가상 메모리가 4GB라면 가상 주소공간은 {0~2^32}
◦ 가상 주소는 실제 메모리 주소가 아니다(가상 메모리에서 자세히 다루겠음)
◦ 프로세스가 가상 주소를 이용하여 요청하면 하드웨어와 OS가 실제 메모리 주소로 번역해 줌
◦ 프로그래머는 실제 메모리와는 상관 없이 연속된 바이트 배열을 이용하는 것처럼 느낌
주소 0
주소 1
주소 15
한 칸 = 1바이트
6. 정보의 저장
◦ 기계수준 프로그램은 데이터 타입(자료형)에 대한 정보를 전혀 가지고 있지 않다.
◦ 기계어 수준에서는 모든 데이터는 단순히 바이트의 연속일 뿐이다.
◦ 바이트의 연속을 DWORD나 WORD단위로 떼어내서 계산하도록 할 수 있지만, 그것은 데이터를 DWORD나 WORD형식으로 보
는 것이 아니라 단순히 4바이트나 2바이트 씩 가져오는 것일 뿐이다.
◦ C에서는 캐스팅을 하지 않으면 잘못된 형식이라고 에러를 내지만, 기계어 수준에서는 단순히 시키는 대로 바이트 덩어리
를 다룰 뿐이라 아무 에러를 내지 않는다.
7. 정보의 저장
◦ 16진수 표시
◦ 1바이트는 8bit이다.
◦ 0 ~ 255 의 범위를 갖는다. (0~2^8-1)
◦ 1바이트는 8개의 0 또는 1로 써야 하지만, 번거롭다. 10진수는 계산이 불편하다.
◦ 그래서 16진수를 많이 사용한다.
◦ 1바이트는 2자리 16진수로 표현 가능하다.
◦ 0x00~0xFF (0~16^15+15 = 16^16 – 1 = 2^8-1)
8. 정보의 저장
◦ 16진수 -> 2진수 변환
◦ 0x173A4C를 2진수로 변환해 보자
◦ 1. 한 숫자 씩 떼어낸다.
◦ 2. 각 숫자를 2진수로 변환한다.
◦ 3. 변환한 2진수를 그대로 붙인다.
◦ 16진수 1 7 3 A 4 C
◦ 2진수 0001 0111 0011 1010 0100 1100
◦ 그대로 붙여 000101110011101001001100이다.
9. 정보의 저장
◦ 2진수 -> 16진수 변환
◦ 100110110110101을 변환해 보자
◦ 1. 밑에서부터 4개씩 끊는다.
◦ 2. 만약 맨 왼쪽의 숫자가 딱 떨어지지 않는다면 앞에 0을 추가한다.
◦ 3. 각각 16진수로 변환한다.
◦ 4. 그대로 붙인다.
◦ 2진수 0100 1101 1011 0101
◦ 16진수 4 D B 5
◦ 그대로 붙여 0x4DB5이다.
10. 정보의 저장
◦ 2진수 -> 16진수 변환
◦ 어떤 값 X가 2의 n제곱이라면 쉽게 계산 가능
◦ X는 맨 앞에 1을 가지고 n개의 0을 가짐
◦ Ex) X = 2^7일 때, X를 2진수로 표현하면 10000000
◦ n을 i+4j, 0<=i<=3으로 표시하면 X는 맨 앞의 16진수로 2^i를 가지고, 그 뒤에 j개의 0을 씀
◦ Ex) n=7일 때 i = 3, j = 1
◦ X를 16진수로 표시하면 0x80 (2^3을 쓰고 j개의 0을 붙임)
11. 정보의 저장
◦ 데이터의 크기
◦ 모든 컴퓨터는 워드 크기의 단위를 가진다.
◦ 여기서 워드는 인텔 MASM 어셈블리어에서의 WORD가 아니다. 그 WORD는 Windows에서 사용하는 자료형이다.
◦ 워드는 주소의 길이이다.
◦ 32비트 컴퓨터는 32비트(4바이트)를, 64비트 컴퓨터는 64비트(8바이트)를 워드 크기로 가진다.
◦ 32비트 컴퓨터는 0~(2^32-1) 범위의 주소를 가질 수 있고, 64비트 컴퓨터는 0~(2^64-1)범위의 주소를 가질 수 있다.
◦ W비트 워드 크기를 갖는다면 주소를 이용하여 2^W크기 만큼의 메모리에 접근할 수 있다.
◦ 32비트 컴퓨터는 한 프로그램이 최대 2^32(4GB), 64비트 컴퓨터는 한 프로그램이 최대 2^64(16EB)만큼의 메모리에 접근할 수 있다.
◦ 워드에 따라(컴퓨터 비트에 따라), 혹은 컴파일러에나 컴퓨터 설정에 따라 정의된 자료형의 크기가 다르다.
◦ C표준에서는 최저 한계 값(int가 최소 몇 바이트여야 한다 같은)은 정의하지만 상위 한계 값은 정의하지 않는다.
◦ int라고 했는데 컴퓨터마다 다르면 헷갈리니까 int32_t, int64_t와 같은 크기가 고정된 자료형을 만들었다.
12. 정보의 저장
◦ 주소 지정과 바이트 순서
◦ 거의 모든 컴퓨터에서 멀티 바이트 객체(int같이 1바이트 이상인 것)는 연속된 바이트에 저장한다.
◦ 객체의 주소는 사용된 바이트의 최소 주소
◦ int가 주소 0x1000, 0x1001, 0x1002, 0x1003에 걸쳐 저장되었다면 그 int 변수의 주소는 0x1000이다.
◦ 멀티 바이트 객체를 표현하는 관습
◦ OS마다, CPU마다 다르다.
◦ 리틀 엔디안
◦ 가장 덜 중요한 바이트부터 저장한다.
◦ 빅 엔디안
◦ 가장 중요한 바이트부터 저장한다.
◦ 한 바이트 내에서 비트들의 순서는 동일하다.
13. 정보의 저장
◦ 리틀 엔디안과 빅 엔디안 차이가 문제가 되는 경우
◦ 네트워크로 데이터를 주고받을 시, 서로 다르게 이해할 수 있다.
◦ 그래서 네트워크로 데이터를 전송할 때는 무조건 빅 엔디안 형식으로 보낸다.
◦ 리틀 엔디안 컴퓨터는 데이터를 빅 엔디안으로 변환한 뒤 보내야 한다.
◦ 정수 데이터를 나타내는 바이트들을 살펴볼 때
◦ 리버싱 시, 메모리에 있는 값을 레지스터에 옮기면 바이트 순서가 뒤바뀌는 것을 볼 수 있다. 이는 메모리에 리틀 엔디안으
로 저장된 값을 가져왔기 때문이다.
◦ 레지스터에는 숫자 그대로(빅 엔디안 형태로) 들어있기 때문에 메모리 덤프에 있는 값과 순서가 달라진다.
◦ 프로그램이 캐스팅이나 union을 이용하여 정상적인 타입 체계를 회피하도록 작성되었을 때
14. 정보의 저장
◦ 부울(Boolean) 대수
◦ 0과 1을 각각 true와 false로 인코딩하면 논리 연산을 적용할 수 있다.
◦ NOT : ! , AND : && , OR : ||
◦ 비트 연산
◦ NOT : ~ , AND : & , OR : | , XOR : ^
◦ 리버싱을 하다 보면 비트 연산을 자주 본다.
◦ 중요 패턴
◦ AND EAX, 0xFF : 맨 뒤 두 자리(1바이트)만 놔두고 위는 0으로 채움
◦ 이런 연산을 마스크를 씌운다고 한다. 비트의 특정 부분을 뽑아내는 것.
◦ XOR EAX, EAX : 자신과 같은 값을 xor하면 0이 된다. Mov EAX, 0보다 빠르기 때문에 초기화 할 때 자주 나온다.
◦ (A^B)^A = B도 성립하여 교묘한 기법을 만들 수도 있다.
15. 정보의 저장
◦ C에서의 연산
◦ Shift
◦ 우측 시프트, 좌측 시프트 ( >>, <<)
◦ 일반적으로 컴퓨터는 두 종류의 우측 시프트를 제공한다.
◦ 논리 우측 시프트 : 좌측 끝에 0을 채움
◦ 비부호형 데이터에서는 이 우측 시프트를 이용해야 한다.
◦ 산술 우측 시프트 : 좌측 끝에 가장 중요한 비트(MSB, 부호 비트)를 채운다.
◦ 부호형 정수 데이터 연산에서 유용하게 쓰임
◦ 자바에서는 >>가 산술, >>>가 논리 시프트로 명확히 정의, 구분한다. 하지만 C에서는 명확히 정의하지 않는다.
◦ 기계어에도 명확히 구분되어 있다. 그 기계어를 C에서 명확히 구분해 쓰는 방법이 없다는 의미.
◦ 대부분의 컴파일러에서는 부호형 데이터에 대해서 시프트 연산을 하는 코드를 만나면 산술 우측 시프트로 컴파일 해 준다.
◦ 곱하기는 매우 느린 연산이다. 그래서 곱하기를 대신하여 shift를 사용한다.
◦ 최적화가 적용된 코드에서 shift를 자주 만날 수 있다.
<산술 우측 shift>
<논리 우측 shift>
17. 정수의 표시
◦ 정수형 데이터 타입
◦ 데이터 타입은 컴퓨터마다 다르지만 보통 이 기준을 지킴
◦ 음수와 양수 범위가 대칭이 아님
◦ 양수가 1 적음
◦ 부호형 인코딩을 보면 이유를 알 수 있다.
18. 정수의 표시
◦ 비부호형 인코딩
◦ 그냥 숫자 이진수 그대로
◦ 비트를 숫자로 변환할 때는 2진수 -> 10진수 계산과 같은 방법으로 변환한다.
◦ Ex) [0101] = 2^2+ 2^0 = 5
◦ 특징
◦ 0과 2^w -1 범위의 수를 표시한다. (w는 비트 수)
◦ 0~2^w -1 사이 모든 숫자가 w비트 값으로 유일한 인코딩을 갖는다.
19. 정수의 표시
◦ 부호형 인코딩
◦ 2의 보수 인코딩
◦ 가장 일반적
◦ 가장 앞의 비트(MSB)에 따라 음수, 양수를 판단할 수 있음(하지만 정확히 부호만 나타내는 것은 아님)
◦ 1이면 음수, 0이면 양수
◦ 0때문에, 그리고 인코딩 방법 자체 때문에 음, 양수의 범위가 대칭적일 수 없다.
◦ 음수의 범위가 1 더 큼
◦ 2의 보수로 인코딩 된 음수 비트를 10진수 값으로 쉽게 변환하는 법
◦ 1. 음수일 경우(MSB가 1일 경우) 비트를 반전한다(NOT 연산)
◦ 2. 반전한 비트에 1을 더한다.
◦ 3. 그 수를 10진수로 변환하고, 앞에 –를 붙인다.
◦ Ex) 1111 -> 비트 반전 : 0000 -> 1 더해서 : 0001 -> -1
◦ -8 + 4 + 2 + 1 = -1
◦ 특징
◦ -2^(w-1) ~ +2^(w -1)-1 범위의 수를 표시한다. (w는 비트 수)
◦ -2^(w-1) ~ +2^(w -1)-1 사이 모든 숫자가 w비트 값으로 유일한 인코딩을 갖는다.
20. 정수의 표시
◦ 2의 보수 인코딩의 범위의 비대칭성이 난해한 오류의 원인이 될 수 있다.
◦ 2의 보수를 이용하는 signed 정수 변수와 unsigned 정수 변수를 섞어 쓰면(캐스팅 등) 문제가 될 수 있다.
◦ Signed 정수에서는 음수인 값이 unsigned에서는 매우 큰 양수가 된다.
◦ 실제로 signed와 unsigned를 섞어 쓴 것이 오류 뿐만 아니라 취약점의 원인이 되는 경우도 있다.
◦ Ex) 옆의 함수에서 get_user_length 함수가 사용자에게 길이를 받아오는 함수라 하자.
◦ 이 함수는 unsigned로 11111111…..1111을 반환했다. 이 값을 signed int에 받으면 -1이다.
◦ 이는 12보다 작다. 따라서 정상으로 인식한다.
◦ 이 예에서는 별 것 아닌 것 같지만, 예를 들어 파일의 앞 부분에 써 있는 길이 등을 읽어오고 실행하는 프로그램의 경우
그 길이를 받아온 뒤 무엇을 하는가에 따라 취약점이 될 수도 있다. 잘못된 범위의 숫자가 적혀 있는 악성 파일을 취약한
애플리케이션으로 실행하는 경우..
21. 정수의 표시
◦ 부호형 인코딩
◦ 기타 인코딩
◦ 1의 보수 인코딩
◦ MSB의 자리 값이 –2^(w-1)이 아니라 –(2^(w-1)-1)
◦ 이외에는 2의 보수와 동일하게 계산
◦ 단순히 비트를 반전하면 음수, 양수가 변환됨
◦ 부호-크기 인코딩
◦ MSB가 부호를 나타내지만, 2의 보수처럼 -2^(w-1)하는 것이 아니라 부호만을 나타냄
◦ 크기는 아래 비트들을 이용하여 계산
◦ 이런 방식은 부동소수점에서 사용된다.
22. 정수의 표시
◦ 비부호형과 부호형 간의 변환
◦ 캐스팅 시 비트 자체는 변하지 않는다. 인코딩을 해석하는 방법이 바뀔 뿐이다.
◦ 부호 -> 비부호 시
◦ 양수일 경우 : 동일한 값으로 해석 됨
◦ 음수일 경우 : 원래 값 + 2^w 만큼의 값으로 해석 됨
◦ 비부호 -> 부호 시
◦ MSB가 0일 경우 : 동일한 값으로 해석 됨
◦ MSB가 1일 경우 : 음수로 해석이 바뀜
23. 정수의 표시
◦ 비부호형과 부호형 간의 변환
◦ 부호 -> 비부호
◦ 0에 가까운 음수일수록 큰 비부호 수로 변환된다.
25. 정수의 표시
◦ C에서의 부호형과 비부호형의 비교
◦ C에서 부호형과 비 부호형을 섞어서 비교할 경우, 묵시적으로 캐스팅이 된다.
◦ 비교하는 대상 중 하나가 비 부호형이면, 부호형을 비 부호형으로 cast한다.
◦ 따라서 계산 결과가 직관적이지 않게 된다.
◦ 이를 피하고 싶다면 비부호/부호형을 섞어 쓰지 말거나 명시적으로 캐스팅 해야 한다.
26. 정수의 표시
◦ 수의 비트 표시를 확장하기
◦ 서로 다른 크기의 자료형에 저장된 값을 옮길 때, 작은 자료형을 큰 자료형으로 옮기는 경우 비트 표시를 확장한다.
◦ 비 부호형 수
◦ 0의 확장
◦ 단순히 앞에 0을 채워 넣음
◦ usx의 비트 : 0x30 39
◦ ux의 비트 : 0x00 00 30 39
◦ 부호형 수
◦ 부호 확장
◦ 2의 보수를 긴 데이터 타입으로 변환할 때, 맨 앞 비트(부호비트)를 채워 넣음
◦ sx의 비트 : 0xCF C7
◦ x의 비트 : 0xFF FF CF C7
◦ 부호형 비 부호형을 섞어서 부호 확장 하는 경우는?
◦ C표준에 의하면, 먼저 크기를 바꾸고 그 다음 자료형을 바꾼다.
◦ ux의 비트 : 0xFF FF CF 27
short sx = -12345;
int x = sx;
unsigned short usx = 12345;
unsigned int ux = usx;
short sx = -12345;
unsigned int ux = sx;
27. 정수의 표시
◦ 수의 비트 표시를 축소하기
◦ 큰 자료형을 작은 자료형에 넣을 때 비트 표시가 축소된다.
◦ 비 부호형 수
◦ 앞의 비트를 없앤다.
◦ K비트를 절삭한 결과 X’의 값은 X mod 2^K와 같다.
◦ 부호형 수
◦ 비 부호형과 똑같이 앞의 비트를 없앤다.
◦ 새로운 맨 앞의 비트가 부호 비트가 된다.
◦ K비트를 절삭한 결과 X’의 값은 U2Tk(B2U(X) mod 2^K))와 같다.
◦ 일단 비트들을 Unsigned로 치고, 같은 방법으로 자른 뒤 잘린 비트를 2의 보수를 해석해는 방식으로 해석한다.
1 0 0 1 0 1 1 0
0 1 1 0
값 : 150 -> 6
1 0 0 1 0 1 1 0
0 1 1 0
값 : -106 -> 6
150 mod 2^4 = 6
29. 정수의 산술연산
◦ 비부호형 덧셈
◦ w비트 비부호형 덧셈 결과의 범위는 0~2^(w+1)-2이다.
◦ 0<=x, y < = (2^w) -1이므로
◦ 이는 덧셈 결과를 표현하기 위해 w+1개의 비트가 필요하게 될 수도 있다는 의미이다.
◦ 컴퓨터에서는 크기가 제한되어 있으므로 위의 경우를 표현할 수 없다.
◦ 제한된 길이로 인해 나타낼 수 없을 때 ‘오버플로우 한다’고 말한다.
◦ W개의 비트로 표현될 수 없는 상황에는 단순히 위의 비트를 삭제한다.
◦ 결과 값 = (실제 숫자 계산 값) mod (2^w)
30. 정수의 산술연산
◦ 비부호형 덧셈
◦ 오버플로우 감지하기
◦ 더한 결과값이 원래 값보다 작은 경우
◦ X+Y의 값이 X, Y보다 작은 경우
◦ C에서는 오버 플로우를 에러로 표시하지 않기 때문에 오류를 직접 검출해야 한다.
◦ C에서는 flag 레지스터에 접근할 수 없기 때문에 위와 같은 특성을 이용하여 검출한다.
31. 정수의 산술연산
◦ 비부호형 덧셈
◦ 교환법칙, 결합법칙 성립
◦ 오버플로우가 생기더라도 교환, 결합법칙은 성립한다.
◦ 모든 원소는 덧셈의 역을 가진다. 다음과 같이 정의된다.
◦ Unsigned 이므로 음수는 아니지만 더하면 0이 되는 값은 있다.
◦ Ex) 111 과 001은 서로의 역이다.
32. 정수의 산술연산
◦ 부호형 덧셈
◦ w비트 부호형 덧셈 결과의 범위는 –2^w ~ 2^(w)-2이다.
◦ -2^(w-1)<=x, y<=2^(w-1)-1 이므로
◦ 값을 표시하기 위해 w+1비트가 필요한 경우가 생긴다.
◦ TMAX를 초과할 때 양의 오버플로우, TMIN보다 작을 때 음의 오버플로우라고 한다.
◦ 비부호형 합과 부호형 합과 정확히 동일한 비트수준 표시를 갖는다.
◦ 대부분 컴퓨터는 비부호형과 부호형을 동일한 기계어 인스트럭션을 이용한다.
◦ 비트 수준에서는 똑같이 계산한다. 결과는 그 비트를 어떤 인코딩으로 해석하느냐에 따른다.
33. 정수의 산술연산
◦ 부호형 덧셈
◦ 오버플로우 감지하기
◦ 양의 오버플로우
◦ X>0, Y>0이면 X+Y>0이어야 한다.
◦ X>0, Y>0일 경우에만 양의 오버플로우가 발생할 수 있다.
◦ 위 상황에서 결과값 S<=0라면 양의 오버플로우가 발생한 것이다.
◦ 음의 오버플로우
◦ X<0, Y<0이면 X+Y<0이어야 한다.
◦ X<0, Y<0일 경우에만 음의 오버플로우가 발생할 수 있다.
◦ 위 상황에서 결과값 S>=0라면 음의 오버플로우가 발생한 것이다.
34. 정수의 산술연산
◦ 부호형 덧셈
◦ 2의 보수에서의 역
◦ 비음수에서의 역과 비트 수준에서 같다.
◦ Ex) 111 과 001은 서로의 역이다.
◦ 대부분의 경우(x>-2^(w-1)인 경우, 즉 MSB만 1인 경우) 해당 값에 –를 취한 값이 된다.
◦ Ex) 2의 보수로 111 = -1, 001 = 1이다.
◦ MSB만 1인 경우(TMIN) 자기 자신이 역이 된다.
35. 정수의 산술연산
◦ 비부호형 곱셈
◦ w비트 비부호형 곱셈 결과의 범위는 0~2^(2w)-2^(w+1)-2이다.
◦ 0<=x, y < = (2^w) -1이므로 0<= x*y <=(2^w -1)^2 의 범위를 가진다.
◦ 이는 곱셈 결과를 표현하기 위해 2w개의 비트가 필요하게 될 수도 있다는 의미이다. (오버플로우)
◦ 오버플로우 되어 넘어가는 비트는 버린다. 따라서 곱셈 결과의 하위 w비트만을 가진다.
◦ 이렇게 비트를 버리는 것은 2^w로 나눈 나머지(mod 연산)와 같다.
36. 정수의 산술연산
◦ 부호형 곱셈
◦ 비부호형 곱셈과 비트 수준에서 똑같은 방법으로 계산한다.
◦ W비트만을 떼어낸 뒤 그것을 2의 보수 형태로 해석한다.
37. 정수의 산술연산
◦ 상수를 사용한 곱셈
◦ 변수끼리 곱하는 것이 아니라 상수를 곱할 때에는 shift연산과 덧셈 등을 이용하여 곱셈을 대신할 수 있다.
◦ 곱셈은 비싼 연산이다. 여러 컴퓨터에서 10개 이상의 클럭 사이클을 필요로 한다.
◦ Shift나 덧셈, 뺄셈 등은 1사이클만 필요로 한다.
◦ 컴파일러가 곱셈을 shift와 덧셈, 뺄셈의 조합으로 대체해 준다.
◦ Ex) X*14하는 코드가 있을 때, 컴파일러는 변수에 14를 곱한다는 것을 알고있다.
◦ 14 = 2^3 + 2^2 + 2^1이다. 따라서 X*(2^3 + 2^2 + 2^1) = (X<<3) + (X<<2) + (X<<1)로 바꿀 수 있다.
◦ 혹은 14 = 2^4 – 2^1을 이용하여 (X<<4) – (X<<1)로 바꿀 수 있다.
◦ 너무 많은 수의 shift와 덧셈이 필요하다면 오히려 곱셈이 빠를 수도 있다.
◦ 대부분의 컴파일러들은 적은 수의 shift, 덧셈, 뺄셈으로 가능한 경우에만 이런 최적화를 진행한다.
38. 정수의 산술연산
◦ 정수의 나눗셈은 항상 0 방향으로 근사한다.
◦ 결과 값이 양수인 경우 반내림, 음수인 경우 반올림한다.
◦ Ex) 나눗셈의 결과값이 2.7이라면 -> 2로 근사 / -2.7이라면 -> -2로 근사
◦ 나눗셈은 곱셈보다도 느리다.
◦ 약 30사이클 이상 소요된다.
◦ Shift 연산을 이용하여 최적화할 수 있다.
◦ 곱셈과 달리 임의의 상수 K로 나누는 것을 2의 제곱으로 나누는 것으로 표현할 수 없다.
◦ 2의 제곱으로 나누는 경우만 가능하다.
◦ 음수를 나눌 경우와 양수를 나눌 경우가 다르다.
◦ 양수를 shift를 이용하여 나눌 경우 자동으로 반내림이 적용된다.
◦ 음수를 shift를 이용하여 나눌 경우 반내림이 된다. (부적절한 근사)
◦ 부적절한 근사를 피하기 위해 음수를 shift하기 전에는 ‘조정값’을 적용해야 한다.
◦ X+(1<<k)-1을 shift해야 반올림된 결과값을 얻을 수 있다.
◦ 이를 C언어 표현으로 정리하면 (X<0 ? X+(1<<k)-1 : X) >> K 이다.
39. 정수의 산술연산
◦ 중요 부분
◦ 정수 산술연산에서, 넘어가는 비트는 그대로 버린다. 이는 modular 연산을 적용한 것과 같다.
◦ 2의 보수는 비 부호형이 사용하는 연산과 같은 방식으로 연산한다.
◦ 비트 수준에서는 동일하거나 매우 유사하지만, 그 계산 결과를 해석하는 방법이 다르다.
◦ 비트는 같지만 인코딩이 다르다.
◦ 부호형을 위한 추가적인 연산 하드웨어가 필요하지 않아 좋다.
◦ ALU는 부호형인지 비 부호형인지를 신경 쓰지 않고 단지 주어진 비트를 연산하기만 하면 된다.
41. 부동소수점
◦ V = X * 2^y 형태로 소수를 인코딩한다.
◦ 옛날에는 CPU회사마다 자신만의 부동소수점 표현 방식을 만들어 이용했다.
◦ 너무 복잡하니 IEEE(아이 트리플 이, 전기 전자 공학자 협회)에서 표준을 만들었다.
◦ 현대 대부분 컴퓨터는 이 IEEE 부동소수점 방식을 지원한다.
◦ 앞으로 배울 것은 이 IEEE 부동소수점 방식이다.
42. 부동소수점
◦ 비율 이진수
◦ 10진수에서 소수는 다음과 같이 표기할 수 있다.
◦ Ex) 5.12 = 10^(1)*5 + 10^(-1)*1 + 10^(-2)*2
◦ 이와 유사하게 2진수로 소수의 유사 값을 표기할 수 있다.
◦ Ex) 101.11(2) = 2^(2)*1 + 2^(0)*1 + 2^(-1)*1 + 2^(-2)*1 = 4+1+1/2+1/4 = 23/4
◦ 소수점을 한 자리 우측으로 이동하면 2를 곱한 효과를 얻는다. 좌측으로 이동하면 2로 나눈 효과를 얻는다.
◦ 부호 ‘.’은 이진 소수점이 되고, 좌측의 비트들은 비음수의 2의 제곱을, 우측은 2의 음의 제곱을 자리 값으로 갖는다.
◦ 유한한 길이의 비트로 이러한 인코딩을 한다면 X*2^y로 나타낼 수 있는 수만 정확히 표시할 수 있다. 다른 값들은 근사할 수밖에 없다.
◦ 정확도를 높이기 위해서는 이진 표시를 늘려야 한다.
◦ 이런 방법을 이용한다면 큰 수를 표시할 때 효율적이지 못하다.
◦ Ex) 5*2^(100)은 비트패턴 101(5)다음에 100개의 0이 따라와야 한다. (1010000………)
43. 부동소수점
◦ IEEE 부동소수점 표시
◦ 이진수의 소수를 저장하는 것이 아닌, 수를 X*2^y형태로 나타낸 뒤 x와 y를 저장한다.
◦ S : 부호. 음수면 1, 양수면 0.
◦ M : 유효숫자. 비율 이진수.
◦ E : 지수. 자리 값을 제공한다. 음수 제곱도 가능하다.
◦ 10진수에서 아래와 같이 표현하는 것과 같은 맥락임. 유효숫자가 비율 이진수이고 base가 2라는 점만 다름.
44. 부동소수점
◦ IEEE 부동소수점 표시의 구현
◦ 32비트의 맨 앞 비트는 부호를 인코딩 한다.
◦ 그 다음 8비트는 지수를 인코딩 한다.
◦ 남은 23비트는 유효숫자를 인코딩 한다.
◦ 지수부는 컴퓨터가 수를 표현하는 일반적인 방식과 다르게 수를 인코딩한다.
◦ 지수부 8비트로 표현할 수 있는 경우 : 256가지
◦ 이것을 반으로 나누어 음수 127개와 0, 양수 128개를 차례대로 대응시킨다.
◦ 지수부에서 표현할 수 있는 가장 작은 값(-127)을 0000 0000으로 표기한다.
◦ Ex) 0000 0000 : -127, 0000 0001 : -126, … , 0111 1111 : 0, 1111 1111 : 128
◦ 지수부의 값은 비트들을 비 부호형처럼 계산하여 얻은 숫자에 -127된 값으로 인식한다.
◦ EX) 00000001이 -126으로 인식된다
◦ 하지만 실제로는 -127을 사용하지 않는다. 지수로 사용할 수 있는 가장 작은 수는 -126이다. 또한 128 역시 사용하지 않는다. 지수로 사용할 수 있는 가장 큰 수는 127이다.
◦ 0000 0000은 실제 숫자 0을 표현하기 위해 예약되어 있다. 1111 1111은 무한대를 표현하기 위해 예약되어 있다.
◦ 2의 보수에서는 음수 범위가 더 넓었는데, 부동 소수점의 지수부는 양수 범위가 더 넓다.
◦ 인코딩이 다른 이유는 일반적인 정수를 나타낼 때와 지수를 나타낼 때, 0과 음수의 의미가 다르기 때문이다.
◦ (표현하고자 하는 숫자 자체가)0인 경우와 무한대를 표현하기 위한 예외 상황을 일관되게 표현하기 위해 (양 끝을 예약해 둘 수 있도록) 실제 값에 일정한 상수(127)를 더해 저장한다.
◦ 이 일정한 상수를 Bias라고 한다.
45. 부동소수점
◦ IEEE 부동소수점 표시의 구현
◦ 가수부(유효숫자)는 비율 이진수를 인코딩한다.
◦ 정규화 과정을 거친 비율 이진수를 인코딩한다.
◦ 정규화 : 소수점 위에 유효숫자 중 한 자리만 남기는 것
◦ Ex) 101.1101(2)를 정규화 하면 1.011101 * 2^2이다. 가수부는 1.011101을 표현한다.
◦ Ex) 0.01010(2)를 정규화 하면 1.010 * 2^(-2)이다.
◦ 정규화 과정을 거치면 숫자가 0이 아닌 이상 맨 앞이 무조건 1이다.
◦ 따라서 맨 앞의 1은 생략한다.
◦ 이로써 비트를 하나 아낄 수 있고 23비트로 2^24범위의 유효숫자를 표현할 수 있게 된다.
◦ Ex) 1.011101(2)를 표현하기 위해 가수부에 011101을 저장한다.
46. 부동소수점
◦ IEEE 부동소수점
◦ 정규화 값
◦ 가장 일반적인 경우.
◦ 정규화 한 비율 이진수를 이용 (암시적 선두 1이 있음)
◦ 비정규화 값
◦ 특별한 경우
◦ 지수 필드가 모두 0일 때
◦ 비율 필드까지 모두 0인 경우 숫자 0을 표현한다.
◦ 부호비트가 0이면 +0.0을, 1이면 -0.0을 나타낸다.
◦ 비율 필드가 0이 아닌 경우 0에 매우 가까운 값을 나타낸다.
◦ 지수 값은 1-bias로 취급한다(-126)
◦ -126인 이유는 비 정규화 값과 정규화 값이 부드럽게 전환되도록 하기 위해서이다
◦ 유효숫자는 암시적 선두 1이 없는 비율 필드 값이다.
◦ 지수값이 -126이지만 비율 이진수 값이 1보다 작으므로 2^(-127)보다 작은 값을 표현할 수 있다.
◦ 특수 값
◦ 지수 필드가 모두 1일 때
◦ 비율 필드가 모두 0이면 무한대를 나타낸다.
◦ 두 개의 매우 큰 값의 곱셈이나 0으로 나눌 때 같은 오버플로우를 나타낼 수 있다.
◦ 비율 필드가 0이 아니면 결과값은 NaN(Not A Number)라고 한다.
◦ NaN은 실수나 무한대가 아닌, −1이나 ∞ − ∞ 같은 연산의 결과를 나타낸다.
11 1 11 1 1 1
11 1 11 111
11 1 11 111
<일반적인 값>
<0>
<매우 작은 값>
<무한대>
<NaN>
1
47. 부동소수점
◦ IEEE 부동소수점
◦ 정규화 값
◦ 지수 필드가 전부 0이거나 전부 1이 아닌 경우
◦ Ex)
◦ 1.00010010000000000000000 * 2^(118)
◦ Ex)
◦ 1.00000000000000000000000 * 2^(-69)
11 1 11 1 1 1
11 1 1
48. 부동소수점
◦ IEEE 부동소수점
◦ 비정규화 값
◦ 지수 필드가 모두 0일 때
◦ 비율 필드까지 모두 0인 경우 0을 나타낸다.
◦ Ex)
◦ 비율 필드가 0이 아닐 때는 0에 매우 가까운 수를 나타낸다.
◦ 비율 필드는 암시적인 선두 1이 없다.
◦ Ex)
◦ 0.10000000000000000000000 * 2^(-126) = 2^(-127)
◦ 지수 필드의 값은 -126이지만 비율 필드가 1보다 작기 때문에 2^(-127)을 표현할 수 있다.
◦ Ex)
◦ 0.00000000000000000000001 * 2^(-126) = 2^(-149)
◦ Float으로 표현할 수 있는 가장 작은 수
49. 부동소수점
◦ IEEE 부동소수점
◦ 특수 값
◦ 지수 필드가 모두 1일 때
◦ 비율 필드가 모두 0인 경우 무한대를 나타낸다.
◦ Ex)
◦ + ∞
◦ Ex)
◦ - ∞
◦ 비율 필드가 0이 아니면 결과값은 NaN(Not A Number)라고 한다.
◦ 다른 수를 0으로 나눌 때는 무한대가 나오지만, 0을 0으로 나눌 때는 NaN이 나온다.
◦ 부호부는 의미를 두지 않는다.
◦ Ex)
11 1 11 111
11 1 11 1111
11 1 11 111 1
50. 부동소수점
◦ IEEE 부동소수점 표시의 구현 정리
• -126~+127 표현 가능 (00000001~11111110)
• 00000000은 숫자 0이나 0에 매우 가까운
수를 표현하기 위해 사용
• 11111111은 무한대나 NaN을 표현하기 위해
사용
• 0이면 양수, 1이면 음수
• 비율 이진수 값이 들어 감
• 일반적인 경우 맨 앞 1을 가정하여 한 비트를 아낌.
• 23비트로 2^24범위의 유효숫자를 표현
• 비 정규화 값일 시 맨 앞 1을 가정하지 않음
51. 부동소수점
◦ IEEE 부동소수점
◦ 단일 정밀도
◦ C에서의 float
◦ 지금까지 본 것
◦ 이중 정밀도
◦ C에서의 double
◦ 64비트를 이용한다.
◦ 원리는 float와 같다.
◦ 부동 소수점 표기법
◦ 부동 소수점 자료형을 출력할 때, 10진수 숫자로 출력하는 경우도 있지만 -4E-1와 같은 형식으로 출력할 때도 있다.
◦ -4E-1는 -0.4를 의미한다. E는 밑수가 10진수라는 의미이고, 뒤의 -1은 지수를 의미한다. 즉 -4*10^(-1)이라는 의미이다.
◦ Ex) 1e10은 1*10^(10)을 의미한다.
52. 부동소수점
◦ 근사법
◦ 부동 소수점은 제한된 범위와 정밀도를 갖기 때문에 실제 연산의 근사값을 사용할 수밖에 없다.
◦ 네 가지 근사 모드가 있다.
◦ 가장 가까운 값으로 정하기 – 짝수 근사
◦ 가장 덜 중요한 숫자가 짝수가 되도록 숫자를 위 혹은 아래로 근사한다.
◦ 0 방향으로 근사하기
◦ 양수는 작은 쪽으로, 음수는 큰 쪽으로 근사
◦ 하향 근사
◦ 양수와 음수를 모두 아래쪽으로 근사
◦ 양수, 음수 모두 작은 쪽으로 근사
◦ 상향 근사
◦ 양수와 음수를 위쪽으로 근사
◦ 양수, 음수 모두 큰 쪽으로 근사
53. 부동소수점
◦ 부동 소수점 연산
◦ 덧셈과 뺄셈
◦ 지수를 비교 -> 지수를 큰 쪽에 맞춰 주기 -> 연산 -> 정규화 하기 때문에 큰 수와 작은 수의 계산에서 작은 수가 무시당할 수 있다.
◦ Ex) (3.14 + 1e10) – 1e10의 결과가 0.0이 된다.
◦ 3.14+(1e10 – 1e10) = 3.14로, 결합법칙이 성립하지 않는다.
◦ 덧셈은 X + Y = Y + X 로 교환법칙은 성립한다.
◦ 대부분은 덧셈에 대한 역이 있지만, 없는 경우도 있다.
◦ 예외 : 무한대와 NaN
◦ 곱셈과 나눗셈
◦ 0인지 확인 -> 지수끼리 가산 또는 감산 -> 유효숫자 곱셈 또는 나눗셈 -> 정규화
◦ 곱셈은 교환 법칙은 성립하지만 결합 법칙은 성립하지 않는다.
◦ 분배법칙은 성립하지 않는다.
◦ (a+b)*c와 a*c + b*c가 다를 수 있다.
◦ 2의 보수나 비 부호형과 다른 점
◦ 단조 특성이 성립한다.
◦ A>=B라면, NaN이 아닌 모든 값에 대해 X+A>=X+B가 성립한다.
55. 직접 손으로 계산해보기
◦ 익숙해져야 실수 없이 계산할 수 있다. 처음 계산을 배운다는 느낌으로 연습해보자.
◦ 계산기를 사용할 것이므로 빠르게 암산하는 수준을 요구하지는 않지만, 최소한 익숙해져야 실수하지 않는다.
◦ 필요할 때 겁내 헷갈림
◦ 1. 0x25B9D2를 이진수로 변환
◦ 2. 이진수 1010111001001001를 16진수로 변환
◦ 3. 0xA8B3D를 이진수로 변환
◦ 4. 이진수 1100100010110110010110를 16진수로 변환
◦ 5. 2^23를 16진수로 표현하면?
◦ 6. 0x2000을 10진수로 표현하면?
◦ 7. 십진수 64를 16진수로 표현하면?
◦ 8. 십진수 123을 16진수로 표현하면?
◦ 9. 0x605C + 0x5
◦ 10. 0x605C – 0x20
◦ 11. 0x605C + 32
◦ 12. 0x60FA - 0x605C
◦ 13. 0x90FB + 0x6
56. 직접 손으로 계산해보기
◦ 14. 0x12345678을 리틀 엔디안 컴퓨터에서 저장한다면 어떻게 저장되는가?
◦ 15. 0x12345678을 빅 엔디안 컴퓨터에서 저장한다면 어떻게 저장되는가?
◦ 16. ~01001110
◦ 17. 01001110 & 11100001
◦ 18. 01001110 | 11100001
◦ 19. 01001110 ^ 11100001
◦ 20. 색을 다음과 같이 RGB의 유무로 표현했다.
◦ A. 보색은 켜 있는 색을 끄고, 꺼진 색을 켜는 방법으로 만들 수 있다. 각각의 보색은 무엇인가?
◦ B. 다음 색들에 대한 부울 연산을 통해 만들어지는 색은?
◦ B.1 파랑| 초록
◦ B.2 노랑 & 청록
◦ B.3 빨강 – 분홍
R G B 색
0 0 0 검정
0 0 1 파랑
0 1 0 초록
0 1 1 청록
1 0 0 빨강
1 0 1 분홍
1 1 0 노랑
1 1 1 흰색
57. 직접 손으로 계산해보기
◦ 21. signed/unsigned 칸은 10진수, 비트는 이진수로 표를 채워보세요
◦ 22. x와 y는 2의 보수이다. 빨간 글씨를 참고하여 빈칸을 채워보세요
비트 signed unsigned
0000 0 0
10
1100 -4
0100 4
15
-12 -15 -27 +5 음의 오버플로우
[100101] [00101]
58. 직접 손으로 계산해보기
◦ 23. 다음은 float 자료형의 비트이다. 비트가 의미하는 숫자는?
◦ 0 10000001 00001000000000000000000
◦ 0 00000000 10000000000000000000000 (수식으로 표현해도 됨)
◦ 1 01111111 10100000000000000000000
◦ 1 11111111 00000000000000000000000
59. 풀이
◦ 1. 0x25B9D2를 이진수로 변환
◦ 16진수 2 5 B 9 D 2
◦ 2진수 0010 0101 1011 1001 1101 0010
◦ 합쳐서 001001011011100111010010
◦ 2. 이진수 1010111001001001를 16진수로 변환
◦ 2진수 1010 1110 0100 1001
◦ 16진수 A E 4 9
◦ 합쳐서 0xAE49
◦ 3. 0xA8B3D를 이진수로 변환
◦ 16진수 A 8 B 3 D
◦ 2진수 1010 1000 1011 0011 1101
◦ 합쳐서 10101000101100111101
◦ 4. 이진수 1100100010110110010110를 16진수로 변환
◦ 2진수 0011 0010 0010 1101 1001 0110
◦ 16진수 3 2 2 D 9 6
◦ 합쳐서 0x322D96
60. 풀이
◦ 5. 2^23를 16진수로 표현하면?
◦ 23 = 3 + 4*5이므로 16진수로 맨 앞에 2^3을 쓰고, 0을 5개 붙인다. 따라서 0x800000
◦ 6. 0x2000을 10진수로 표현하면?
◦ 맨 앞만 다른 수이고 뒤는 전부 0이므로 2의 n제곱임을 알 수 있다.
◦ 1+4*3 = 13이므로 n은 13이다. 즉, 2^13이고 이는 10진수로 8192이다.
◦ 16^3*2 = 2^12*2 = 2^13으로 계산해도 빠르다.
◦ 7. 십진수 64를 16진수로 표현하면?
◦ 64 = 2^6
◦ 6 = 2+4*1 이므로 16진수로 0x40
◦ 8. 십진수 123을 16진수로 표현하면?
◦ 배수가 아닌 경우 직접 나누어야 한다.
◦ 123 = 16*7 + 11 이므로 16진수로 0x7B
61. 풀이
◦ 9. 0x605C + 0x5
◦ 0x6061
◦ 10. 0x605C – 0x20
◦ 0x603C
◦ 11. 0x605C + 32
◦ 주의! 32에는 16진수임을 표시하는 0x가 붙지 않았다. 이는 디폴트로 10진수를 의미한다.
◦ 실제로 16진수를 사용하다 보면 10진수와 헷갈려서 헤매는 일이 많다. 어느 한 쪽을 잘못 해석하면 꼬인다.
◦ 0x605C + 0x20 = 0x607C
◦ 12. 0x60FA - 0x605C
◦ 뺄셈 받아 내림에 주의한다.
◦ 0x9E
◦ 13. 0x90FB + 0x6
◦ 덧셈 받아 올림에 주의한다.
◦ 0x9101
62. 풀이
◦ 14. 0x12345678을 리틀 엔디안 컴퓨터에서 저장한다면 어떻게 저장되는가?
◦ 바이트 단위로 거꾸로 저장되므로 78 56 34 12 순서로 저장된다.
◦ 15. 0x12345678을 빅 엔디안 컴퓨터에서 저장한다면 어떻게 저장되는가?
◦ 그대로 저장되므로 12 34 56 78 순서로 저장된다.
◦ 16. ~01001110
◦ 10110001
◦ 17. 01001110 & 11100001
◦ 01000000
◦ 18. 01001110 | 11100001
◦ 11101111
◦ 19. 01001110 ^ 11100001
◦ 10101111
63. 풀이
◦ 20. 색을 다음과 같이 RGB의 유무로 표현했다.
◦ A. 보색은 켜 있는 색을 끄고, 꺼진 색을 켜는 방법으로 만들 수 있다. 각각의 보색은 무엇인가?
◦ NOT 연산을 통해 찾을 수 있다. 답은 표에.
◦ B. 다음 색들에 대한 부울 연산을 통해 만들어지는 색은?
◦ B.1 파랑| 초록
◦ 011이므로 청록색이다.
◦ B.2 노랑 & 청록
◦ 010으로 초록색이다.
◦ B.3 빨강 – 분홍
◦ 001로 파랑색이다.
◦ 21. signed/unsigned 칸은 10진수, 비트는 이진수로 표를 채워보세요
R G B 색 보색
0 0 0 검정 흰색
0 0 1 파랑 노랑
0 1 0 초록 분홍
0 1 1 청록 빨강
1 0 0 빨강 청록
1 0 1 분홍 초록
1 1 0 노랑 파랑
1 1 1 흰색 검정
비트 signed unsigned
0000 0 0
1010 -6 10
1100 -4 12
0100 4 4
1111 -1 15
66. 참고 사이트
◦ 부동 소수점 설명
◦ http://thrillfighter.tistory.com/349
◦ 무한대 관련 설명은 잘못 됐지만 일반적인 설명은 잘 되어 있음
◦ http://egloos.zum.com/studyfoss/v/4956717
◦ 부동 소수점 계산기
◦ https://www.h-schmidt.net/FloatConverter/IEEE754.html
◦ 부동 소수점 계산하는 법
◦ http://toelgob.tistory.com/16