Integer Addition & Subtraction
컴퓨터에서의 정수형 덧셈
- 결과가 표현 가능한 범위를 벗어나면 Overflow가 일어난다.
- 양 + 음의 덧셈에서는 Overflow가 일어나지 않는다.
- 양 + 양의 덧셈에서 Overflow가 일어날 수 있다. (MSB가 1로 carry되면서 음수화 발생)
- 음 + 음의 덧셈에서 Underflow가 일어날 수 있다. (MSB가 1->0으로 되면서 양수화 발생)
컴퓨터에서의 정수형 뺄셈
- 정수형 뺄셈은 빼지는 수를 음수(2의 보수 + 1)로 만들고 덧셈을 진행하면 된다.
- 양 - 음의 뺄셈에서 Overflow가 발생할 수 있고, 음 - 양의 뺄셈에서 Underflow가 발생할 수 있다.
Dealing with Overflow
몇몇 언어에서는 Overflow를 무시한다. (발생해도 그냥 무시하고 그 값을 쓴다.)
- MIPS Instruction에서는 addu, addui, subu가 무시
다른 언어는 예외를 발생시킨다.
- MIPS Instruction에서는 add, addi, sub가 발생
- Overflow가 발생하면, exception handler를 호출해 미리 정의된 handler의 주소로 jump
Multiplication
Multiplication Hardware (First ver.)
Optimized Multiplier Hardware
Add and Right Shift
6 * 5의 예제로 보자 (4-bit ALU, Multiplicand, 8-bit product)
Multiplicand: 0110 (6)
product: 0000 0101 (5)
- 시작 : 0000 0101
- add : 0110 0101
- shift: 0011 0010 (마지막 bit이 0 -> 그대로 내려옴)
- add(x): 0011 0010
- shift: 0001 1001 (마지막 bit이 1 -> add 진행)
- add: 0111 1001
- shift: 0011 1100 (마지막 bit이 0 -> 그대로 내려옴)
- add(x): 0011 1100
- shift: 0001 1110 => 30
4-bit multiplicand의 곱셈이므로, 4번 shift 진행.
n-bit multiplicand의 곱셈 -> (add/shift n번 진행)
Division
Dividend = quotiend * divisor + remainer
Optimized Divider (Sequencial ver.)
Left shift and Subtraction
7 / 2의 예제로 보자 (ALU와 divisor는 4-bit. dividend는 8-bit)
divisor = 0010(2), dividend = 0000 0111(7), sub = 1110 (-2)
- 처음 : 0000 0111
- shift : 0000 1110
- sub : 1110 1110 (가장 왼쪽 bit = 1, 복구)
- 복구 : 0000 1110
- shift : 0001 1100
- sub : 1111 1100 (가장 왼쪽 bit = 1, 복구)
- 복구 : 0001 1100
- shift : 0011 1000
- sub : 0001 1001 (1110 + 0011 => 10001, 0001에 carry된 1은 오른쪽에 붙는다. 가장 왼쪽 bit = 0, 그대로)
- shift : 0011 0010
- sub : 0001 0011
4-bit divisor이므로, 4번의 shift/sub 진행하면 종료.
몫: 0011(3), 나머지: 0001(1)
Floating Point
컴퓨터의 부동소수점 표현
- 실수를 표현하기 위해 정수부가 1의 자리인 표현을 정규화된 표현(normalized), 아닌 표현을 not normalized
- 2진 표현으로는
+-1.xxxxx * 2^(yyy)
IEEE Floating-Point Format
IEEE에 의해 정의된 부동소수점 정규 표현
single-precision(32bit), double-precision(64bit)
E를 늘리면 표현할 수 있는 범위가 늘어나고, F를 늘리면 표현하는 값의 정확도가 높아진다.
-0.75를 IEEE 754의 정규 표현으로 나타내보자.
- 먼저 -0.75를 2진수로 바꾼다. -> -0.11_2
- -0.11_2를 정수부가 일의 자리인 표현으로 바꾼다. -> -1.1 * 2^(-1)
=> S = 1, Fraction = 10000...00, Exponent = -1 + 127(single) = 126
따라서 single precision으로 나타내면 1 011111110 10...00이다.
하나 더, -118.625를 바꿔보자.
- -118.625를 2진수로 바꾼다. -> -1110110.101_2
- 이것을 정수부가 일의 자리인 표현으로 정규화 -> -1.110110101 * 2^6
=> S = 1, Fraction = 110110101000..00 (총 26bits), Exponent = 6 + 127(single) = 133
따랏 single precision으로 나타내면 1 10000101 11011010100000..00이다.
IEEE 754 FP Standard Encoding
true zero (0)
- Exponent와 Fraction이 전부 0.
denormalized number
- Exponent가 0b00..0라면 Fraction의 hidden bit을 0으로 둔다. (원래라면 hidden bit은 1)
- 여기서 Fraction도 0이라면 true zero
infinity
- Exponent=0b1111..11이고, Fraction=0b000..00 => 무한대
not a number (NaN)
- Exponent=0b1111..11이고, Fraction!=0b000..00 => NaN
Floating-Point Addition
정수부는 정수부끼리, 소숫점은 소숫점끼리
0.5 - 0.4375 = 0.0625 를 예시로
1. 소숫점 정렬 (작은 수를 큰 수의 자릿수에 맞춘다.)
- 0.5 = 1.0000 * 2^(-1), -0.4375 = -1.1100 * 2^(-2)
- 절댓값이 더 큰 0.5에 자릿수를 맞춘다. -> -1.1100 * 2^(-2) = -0.1110 * 2^(-1)
2. 정수부끼리 계산
- 둘을 계산하면 0.0010 * 2^(-1)
3. 결과를 normalize
- 1.000 * 2^(-4)
4. 필요하다면 반올림하거나 비정규화
- 반올림 필요 x, 비정규화 필요 x
- S = 0, Exponent = -4 + 127(single) = 123, Fragment = 0000...00
소숫점 반올림
Guard - Rount - Sticky
- 근사하는 자릿수의 오른쪽 3개의 bit를 GRS로 두고, 100보다 크면 올림, 작으면 내림
- 100이라면 Sticky가 1이 있으면 올림
예시) 2.710을 FP로 표현할 때, 2^(-5) 자리수에서 반올림하기
2.710 = 10.101101... = 1.0101101.. * 2^1
여기서 반올림한다면
1.0101101... -> 1.0110
따라서 1.0110 * 2^1
Floating-Point Multiplication
0.5 * -0.4375 = -0.21875를 예시로
0.5 = 1.000 * 2^(-1), -0.4375 = -1.110 * 2^(-2)
1. e1+e2-bias
- 0.5의 exponent=-1, -0.4375의 exponent=-2
- -1 + (-2) + 127 = 124
2. 곱하기
1.000 * 1.110 = 1.110
3. 결과를 정규화
1.110 * 2^(-3)
4. 피연산자들의 부호로부터 결과 부호 결정
- 부호는 음수
Fallacies