-
Chapter 3 : Float컴퓨터 시스템 개론 2022. 3. 27. 18:24728x90
1011(Integer part).101(Decimal part)
소수점 기준으로 왼쪽은 정부부분, 오른쪽은 실수부분입니다.
ex)
5 + 3/4 = 101.11(2)
2 + 7/8 = 10.111(2)
1 + 7/16 = 1.0111(2)
Floating Point(부동 소수점) Representation
좀더 정확한 수를 표현하기 위함입니다.
맨 위에 있는 것이 보통 float형으로 사용됩니다.
더 정확히 수를 표현하기 위해 bit 수를 늘린게 double 형입니다.
bit가 늘어날 수 록 표현하는 수는 더 정확해집니다.
Normalized Values
s는 sign bit를 의미, M은 실수부분, E는 지수 부분을 의미합니다.
위에 봤던것과 같이 우리가 흔히 사용하는 실수 표현방식 입니다.
부동소수점 표현식에서 exp의 bit가 모두 0이 아니거나 1이 아닐때 사용합니다.
E = exp - bias
bias지수는 2^(k-1)-1 이며 k는 지수 bit의 개수입니다.
즉, Single precision(32 bit)에서는 bias 지수는 127 (exp : 1 ~ 254, E = -126 ~ 127)
Double precision(64 bit)에서는 bias 지수는 1023입니다. (exp : 1 ~ 2046, E = -1022 ~ 1023)
M = 1 + f = 1.xxxxxxxxx...
ex) float F = 15213.0
Denormalized Values
exp 의 모든 bit가 0일때 사용합니다.
E = 1-bias 입니다.
M = f = 0.xxxxx...
denormalized value는 두가지 목적을 위해 존재합니다.
1. 숫자 0을 표현하기 위해 제공합니다.
normarlized value는 항상 M >= 1 이므로 0을 표현할 수 없습니다.
+0.0 은 bit가 모두 0인 패턴을 지닙니다. s = 0, exp = 0, f = 0 입니다.
반대로 부호 bit만 1이고 나머지가 0이면 -0.0의 값을 가집니다.
0.0에 매우 가까운 수를 표현하기 위한 함수가 존재합니다. 바로 gradual underflow입니다.
Special Values
exp bit가 모두 1이고 f의 bit가 모두 0이면 ∞입니다. s가 0이면 +∞, 1이면 -∞ 입니다.
무한대는 엄청 큰 두 수를 곱할 때나, 0으로 나눌 때 overflow결과가 나올 수 있습니다.
예를 들어 1.0 / 0.0 = -1.0 / -0.0 = +∞, 1.0 / -0.0 = -∞
exp bit는 모두 1이지만 f의 bit가 0이 아니면 "NaN" (Not a Number) 이라는 결과가 나옵니다.
즉, 무한대나 실수로 표현할 수 없는 부분입니다.
예를들어 복소수(sqrt(-1)), ∞ - ∞, ∞ * 0 등등
Tiny Floating Point
위에서 본 32 bit, 64 bit는 너무 큰 수와 너무 작은 수를 표현하기에 복잡합니다.
따라서 8 bit로 지금까지 배운내요을 적용해 봅니다.
bias 지수는 2^(4-1)-1 = 7 입니다.
먼저 Exponent를 살펴보면 exp는 4 bit로 구성되어 있기 때문에
normalized에서는 1 ~ 14까지 exp부분을 표시할 수 있습니다.
denormalized인 smallest positive를 살펴보면 denormalized의 M값은 1 - bias 입니다.
따라서 모든 denormalized의 E는 -6입니다. 그러므로 2^E 값도 항상 1/64 입니다.
그럼 M을 살펴보기 위해 f를 살펴보면 분수부분은 0.001 이니 1/8이 됩니다.
denormalized에선 M이 항상 1보다 작으므로 M = f = 1/8이 됩니다.
V는 표에서 보듯이 f의 분자가 1늘때 마다 분자가 1늘어납니다.
Distribution of Values
위 표를 보면 군데군데 표현을 하지 못하는 수들이 존재합니다.
보통 8 bit는 (2^8)-1 = 255만큼 표현이 가능하지만 위의 표를 보면 largest nomalized가 240입니다.
만약 우리가 나타내고자 하는 수가 230이라면 위의 표를 기준으로 230과 가까운 224가 출력됩니다.
float는 굉장히 큰 수 와 작은 수를 표현하기 위해 만들어졌기 때문에 정수와 달리 표현하지 못하는 숫자가
존재합니다. 물론 현재 컴퓨터는 32 bit, 64 bit를 지원하여 비정상적인 수가 아니면 거의 다 표현이 가능합니다.
위 그림은 실수의 표현가능함 범위를 보여줍니다.
특징을 보면 exp가 같은 수끼리는 다음 수를 표현하는 수까지 거리가 일정합니다.
예를들어 8 bit에서 가장 큰 수인 240(0 1110 111)과 1 fration이 차이나는 224(0 1110 110)와의 거리는
16이 납니다. 그럼 16이란 차이는 0 1110 000까지 유지됩니다.
그 다음 exp부분이 1101 부분 부터는 16이 아니 다른값의 간격으로 차이가 납니다.
지금까지는 normalized한 경우이고 denormalized는 smallest normalized의 exp와 같은 간격으로
숫자를 표현합니다. 이런 이유는 0을 표현가능하게하기 때문입니다.
만약 exp가 작아질 수록 거리가 작게되면 영원히 0에 닿지 못하게 됩니다.
따라서 denormalized는 normalized의 최소값과 같은 간격으로 숫자를 표현합니다.
이것이 바로 Gradual underflow입니다.
Special Properties of the IEEE Encoding
두 실수를 비교하는 방법입니다.
1. sign bit 확인하기
2. -0 = 0입니다.
3. NaN 인지 확인
4. denormalized vs normalized & normalized vs infinity
5. 나머지는 exp와 f부분만 확인하면 됩니다.
Rounding
실수를 표현하는과정에서 우리는 정확히 어떤 실수에 접근하지 못할 수 있습니다.
그러한 단점을 보완하기 위해 Rounding(반올림)기법을 사용합니다.
총 4가지 반올림 기법이있습니다.
이중에서 기본값은 Round-to-even 입니다. 즉, 짝수와 가까운곳으로 올림해주는 방식입니다.
예를들어 우리는 보통 1.5 같은 수는 그냥 2로 올림을 해주었습니다.
마찬가지로 Round-to-even은 1.40은 1로, 1.60은 2로 1.50은 짝수 2와 가깝기 때문에 2로 올림해줍니다.
반면에 2.50은 짝수 2와 4중에서 2와 가까우므로 2로 내림해줍니다. -1.50도 -2로 내림해줍니다.
Round-toward-zero은 양수는 내림하고 음수는 올림해줍니다.
Round-down은 양수와 음수 모두 내림해줍니다.
Round-up은 양수와 음수 모두 올림해줍니다.
이것을 binary 실수에 적용하는법을 봅니다.
binary 실수에서 짝수, 홀수를 판단하는 방법은 소수점 마지막 자리가 0이면 짝수, 1이면 홀수입니다.
우리가 반올림 할때 0.5를 기준으로 하듯이 마찬가지로 binary 실수에서도 중간값 100...을 기준으로 판단합니다.
예를 들어서 실수를 소수점 아래 2번째로 round-to-even을 하게 되면
근사할 값(10진수) 이진수 근사결과(이진수) 근사결과(10진수)
2 + 3/32 10.00011 10.00 2
2+3/32를 이진수로 표현하면 10.00011이고 소수점아래 2번째로 판단하면 011입니다.
이를 중간값 100과 비교해주면 100 > 011 이므로 내림해주면 됩니다. 따라서 10.00이 되고 10진수로 2입니다.
근사할 값(10진수) 이진수 근사결과(이진수) 근사결과(10진수)
2 + 7/8 10.11100 11.00 3
2+7/8을 이진수로 표현하면 10.11100이 되고 소수점 아래 2번째로 판단하면 100입니다.
이를 중간값 100과 비교하면 100 = 100 이므로 이 실수가 짝수인지 홀수인지 판단해야합니다.
10.11100 소수점 마지막 자리가 1이므로 홀수입니다. 현재 홀수이므로 올림을 해주면 짝수와 가깝게됩니다.
따라서 올림해줍니다. 11.00이 되고 10진수로 3입니다.
근사할 값(10진수) 이진수 근사결과(이진수) 근사결과(10진수)
2 + 5/8 10.10100 10.10 2 + 1/2
2+5/8을 이진수로 표현하면 10.10100이 되고 소수점 아래 2번째로 판단하면 100입니다.
이를 중간값 100과 비교하면 100 = 100 이므로 이 실수가 짝수인지 홀수인지 판단해야합니다.
10.10100 소수점 마지막 자리가 0이므로 짝수입니다. 현재 짝수이므로 내림을 해주면 짝수와 가깝게 됩니다.
따라서 내림해줍니다. 10.10이 되고 10진수로 2 + 1/2가 됩니다.
Round-to-even을 할때 사용합니다.
예를 들어 10.00011을 소수점 2번째 자리로 근사할 경우
Guard bit = 0
Round bit = 0
Sticky bit = 11이 됩니다.
Floating Point Addition
두 수를 덧셈한다고 하자 그럼 밑과 같이 결과가 나옵니다.
E1 > E2 라고 가정 해보자
sign값을 확인하는 방법은 절댓값을 확인해봐야합니다. 두 수의 절댓값을 확인해 더 큰수의 sign에 맞춰야합니다.
그 다음 M1과 M2는 바로 더하면 안되고 E1과 E2를 맞춘(sign allign)후 진행해야합니다.
E1 > E2로 가정하였으므로 E = E1이 됩니다.
이제 결과값이 주어진 bit보다 클경우에는 Fixing작업을 해야합니다.
1. M >= 2 일 경우 M을 오른쪽으로 shift해 이에 맞춰 E값을 증가시켜줘야 합니다.
2. M < 1 일경우 M을 왼쪽으로 shift해 이에 맞춰 E값을 감소시켜 주어야 합니다.
3. 증감시킨 E값이 범위 밖으로 나가면 overflow가 됩니다.
4. M을 Rounding해주고 fration위치에 맞게 fit해줍니다.
Floating Point Multiplication
두 수를 곱셈한다고 하자, 그럼 밑과 같이 결과가 나옵니다.
먼저 sing값을 먼저 살펴보면 부호가 같다면 무조건 양수, 다르다면 음수이기 때문에
s = s1 ^ s2 (s1 XOR s2) 로 표현이 가능합니다.
M값은 그냥 M1 * M2 해주면 됩니다.
E값도 그냥 지수 곱셈과 같이 E = E1 + E2가 됩니다.
마찬가지로 Fixing이 필요합니다.
1. M >= 2 이면 M은 오른쪽으로 shift하고 E를 이에 맞게 증가시켜줍니다.
예를들어 M을 1만큼 shift해주면 E를 1만큼 올립니다.
2. E가 범위를 넘어가면 overflow가 됩니다.
3. 마지막으로 M을 Rounding해주고 fraction위치에 맞게 fit해줍니다.
Floating Point in C
C언어에는 실수형 data type을 float와 double이 존재합니다.
float는 single precision이므로 32 bit
double은 double precision이므로 64 bit
이제 Casting하는과정을 살펴보면
int -> float로 변환하면 int 값은 32 bit 모두 정수를 저장하지만 float는 23 bit만 fraction을 저장하기에 rounding이
일어납니다.
int, float -> double로 변환하면 double은 52 bit의 frac를 보유하므로 정상적으로 casting이 됩니다.
double -> float는 float의 frac bit가 부족하므로 rounding이 일어납니다.
float, double -> int는 float또는 double이 int로 저장되는 과정에서도 rounding이 발생합니다.
Byte-Oriented Memory Organization
프로그램은 주소별로 데이터를 참조합니다.
메모리는 개념적으로 매우 큰 byte 배열로 간주합니다.(실제로는 그렇지 않음 그냥 상상으로만)
주소는 해당 배열의 인덱스와 같으며 포인터 변수는 주소를 저장합니다.
시스템은 각 process에게 개인 address space를 제공합니다.
따라서 프로그램은 자신의 데이터를 다룰 수 있지만 다른 데이터는 그러지 못합니다.
Word-Oriented Memory Organization
주소들은 byte 위치를 지정합니다.
주소는 word의 첫번째 byte의 주소입니다.
32 bit OS에서는 4GByte를 지원합니다.
(2^30 * 4 * 1 byte)
Byte Ordering
다수의 byte에 해당하는 데이터를 메모리에 위치시키는 방법입니다.
Big Endian : 데이터를 차례대로 주소의 낮은 위치부터 넣습니다.
보통 Sun, PPC, Mac, Internet에서 사용합니다.
Little Endian : Big Endian과 반대로 넣습니다.
보통 x86, ARM, Android, iOS, Windows에서 사용합니다.
예를들어 int x = 0x1234567이라고 하면
int &x = 0x100
10진수 15123
2진수 0011 1011 0110 1101
16진수 3B6D
'컴퓨터 시스템 개론' 카테고리의 다른 글
Chapter 7 : Machine-Level Programming 3 (Procedure) (0) 2022.04.25 Chapter 6 : Machine-Level Programming 2 (Control) (0) 2022.04.06 Chapter 5 : Machine-Level Programming 1 (Basis) (0) 2022.03.30 Chapter 2 (Bits, Bytes, and Integers) (0) 2022.03.22 chapter 1 (0) 2022.03.05