## 목차 ##

  1. ALU의 구성요소
  2. 정수 표현방식
  3. 논리연산
  4. 시프트연산
  5. 정수 연산
  6. 부동소수점 표현방식
  7. 부동소수점 연산


## 0. Intro ##

컴퓨터의 출발은 4칙연산 계산기이며 지금도 근본적인 기능은 수치의 산술연산 및 논리 연산이다. 산술연산은 정수와 이외의 실수(부동소수점으로 표현)에 대한 계산이고 논리연산은 2진수로 표현되는 데이터에 대하여(AND, OR, NOT 등) 이루어진다.

이 장에서는 산술 및 논리연산을 수행하는 CPU의 핵심 부품인 산술논리연산장치(ALU - Arithmetic and Logical Unit)의 내부 구성과 연산 방법에 대한 내용이다.


## 1. ALU의 구성요소 ##

ALU는 CPU를 구성하는 모듈들 중 하나로 수치 및 논리 데이터에 대한 연산을 수행하는 하드웨어이다. ALU의 내부 구성요소들은 아래와 같다.

1) 산술연산장치

4칙연산 수행

2) 논리연산장치

논리연산(AND, OR, NOT, NOR, XOR 등)을 수행

3) 시프트 레지스터(shift register)

비트를 좌,우로 이동

4) 보수기(complementer)

2의 보수 출력

5) 상태 레지스터(status register)

연산 결과의 상태를 나타내는 플래그(flag)들을 저장

alu_modules

ALU는 CPU의 제어유닛으로부터 오는 제어신호를 받아 계산에 필요한 모듈을 선택하여 연산을 수행하고 결과의 상태들을 상태 레지스터에 저장한다. 상태 레지스터의 플래그들은 조건 분기 등의 이후 프로그램 실행에 사용된다.


## 2. 정수 표현방식 ##

컴퓨터는 2진수(binary number) 시스템을 사용하므로 모든것을 0과 1로 표현할 수 밖에 없다.

만약 음수가 없고 양수만 존재한다면 표현 방법은 수학시간에 배운 일반적인 2진수 표현 방법만큼 간단하다. 예를들어 8bit를 사용해 10진수 60을 나타낸다면 00111100처럼 쓸 수 있다. 혹은 255를 나타낸다면 11111111이 된다.

그러나 컴퓨터는 음수도 표현해야 하므로 부호 비트(sign bit)를 사용한다. 부호비트를 사용하는 2진수 표현에는 3가지 방법이 있다.

a) 부호화-크기 표현

최상위 비트(MSB - Most Significant Bit)가 0이면 양수, 1이면 음수이다. MSB를 제외한 하위 비트들은 수의 크기를 나타낸다.

ex1) 8bit를 이용한 +10 표현 -> 00001010
ex2) 8bit를 이용한 -10 표현 -> 10001010

이 방법의 단점 중 첫번째는 두 개 이상의 정수사이 연산과정에서 부호를 별도로 처리해야한다는 점이다. 두 번째는 0을 표현하는 경우가 2가지가 된다는 점이다. 이 경우 데이터가 '0'인지 검사하는 과정이 더 복잡해진다.

부호화-크기 표현에서 n비트가 표현할 수 있는 수들의 갯수는 (2^n-1) 개이다.

b) 보수 표현

보수(complementary number)의 어원적 의미는 상호보완하는 수이다. 보수에는 2가지 종류가 있다. n진법에는 (n-1)의 보수와 n의 보수가 존재한다. 따라서 10진법에서는 9의보수와 10의보수가 사용된다.

274의 9의 보수는 (999-274) = 725이며, 10의 보수는 (1000-274) = 726이다.

마찬가지로 2진법에서는 1의보수와 2의보수가 존재한다. 100101의 1의 보수는 모든 비트를 반전시켜 011010이 되며, 2의 보수는 1의 보수에 1을 더한 011011이 된다.

정리하면 아래와 같다.

1) 1의 보수 : 모든 비트를 반전시킨다.(0 -> 1, 1 -> 0)

2) 2의 보수 : 모든 비트를 반전시키고(1의 보수를 취하고) 1을 더한다.

일반적으로 거의 모든 컴퓨터의 숫자 체계는 2의 보수표현을 사용한다. 이유는 2의 보수 표현이 1의 보수 표현보다 표현할 수 있는 수의 가짓수가 1개 더 많기 때문이다. 1의 보수 표현에서는 부호화-크기 표현과 마찬가지로 0에 대한 표현이 2가지 존재한다.

아래 표는 8비트를 사용하여 표현할 수 있는 수의 범위를 1의 보수 표현과 2의 보수 표현으로 나타낸 것이다.

complement_representation

결론적으로 컴퓨터의 정수 체계를 이해한다는 것은 2의 보수 표현을 이해한다는 것이다.

a) 10진수 -> 2진수 변환

양수 : 일반적인 2진수 계산

음수 : 매칭되는 양수의 2진수를 계산 후 2의 보수로 변환(비트 반전 -> 1 더하기)

ex) -100을 8bit의 2진수로 변환 : 100은 2진수로 01100100이고 이를 비트 반전시키면 10011011이며, 1을 더하면 최종적으로 10011100이 된다.

b) 2진수 -> 10진수 변환

양수 : 일반적인 2진수 계산

음수 : MSB가 1일 것이므로 n비트의 경우 -2^(n-1)에다가 나머지 비트들을 10진수로 변환 후 더하기

ex) 10011100 = -2^7 + 2^4 + 2^3 + 2^2 = -128 + 16 + 8 + 4 = -100


## 3. 논리 연산 ##

논리 연산은 비트 단위로 의미를 가지며, 연산도 비트 단위로 처리된다. 1비트 사이의 기본적인 논리 연산이 아래 표와같이 정리되었다.

logical_operation

참고로 XOR 연산은 exclusive-OR 이라는 의미로서 두 비트가 서로 다른 경우에는 결과가 1, 같은 경우에는 0이 된다.

위의 논리 연산을 위한 실제 하드웨어는 아래 그림과 같이 설계될 수 있다.

logical_operation_unit

입력비트 A와 B는 모든 게이트들을 통과하지만 두 개의 선택 신호(Selection Bit)에 의해 어떤 게이트의 결과가 출력되어 F로 나갈지 선택된다.

위의 논리연산 모듈을 n개 이어붙이면 n-bit 데이터 사이의 논리연산도 가능해진다. 아래 그림은 4bit 데이터 사이의 논리 연산을 위한 장치이다.

logical_operation_module

데이터의 처리는 CPU의 워드(word) 단위로 처리되므로 실제 CPU 하드웨어에는 논리연산 유닛을 n개 이어붙인 형태가 될 것이다.


## 4. 시프트 연산 ##

1) 논리적 시프트 연산

데이터 내의 모든 비트를 왼쪽, 혹은 오른쪽으로 한 칸씩 이동시키는 연산이다. 예를들어 좌측 시프트(shift left) 연산을 수행하면 모든 비트가 왼쪽으로 한칸씩 이동한다. 이 때 최상위 비트(MSB - Most Significant Bit)는 날아가고 최하위 비트(LSB - Least Significant Bit)에는 0이 채워진다.

logical_shift

가령 11001011을 좌측 시프트연산 시키면 10010110이 된다. 우측 시프트연산 시키면 01100101이 된다.

아래는 시프트 레지스터의 내부 구성도이다.

logical_shift_unit

위 그림에서 좌측 시프트 신호(L)를 1로 SET하면 오른쪽 플립플롭의 출력(Q)과 AND연산이 되어서 왼쪽 플립플롭의 입력(D)로 들어가게 된다. 이 때 가장 오른쪽의 AND게이트의 입력으로는 0이 들어와 가장 오른쪽 플립플롭에는 0이 채워진다다.

우측 시프트 신호(R)를 1로 SET하면 왼쪽 플립플롭의 출력(Q)과 AND연산되어 오른쪽 플립플롭의 입력(D)로 들어가게 된다. 이 때 가장 왼쪽의 AND게이트 입력으로 0이 들어와 가장 왼쪽 플립플롭에는 0이 채워진다.



2) 순환 시프트 연산

순환 시프트(circular shift) 연산은 논리적 시프트 연산과 같지만 MSB나 LSB를 버리지 않고 반대편 끝에있는 비트 위치로 이동시키는 것이다. 아래 그림은 순환 좌측 시프트 연산을 보여준다.

circular_shift_left

위 그림에서는 MSB가 버려지는 대신 0으로 채워질 LSB 위치로 이동하는 것이다.

결론적으로 논리적 시프트 연산과 다르게 비트가 버려지거나 0으로 채워지는 대신 버려질 비트를 0으로 채워질 비트 자리에 채우는 것이다.



3) 산술적 시프트 연산

부호비트를 고려하여 수행되는 논리적 시프트 연산이다. 부호 비트는 변하지 않는다는 특징이 있다.

a) 산술적 좌측 시프트 연산 : MSB는 변하지 않고 나머지 비트들에 대해 논리적 좌측 시프트가 수행된다. LSB는 0으로 채워진다.

b) 산술적 우측 시프트 연산 : MSB는 변하지 않고 나머지 비트들에 대해 논리적 우측 시프트가 수행된다. MSB의 바로 오른쪽 비트는 MSB와 같은 비트로 채워진다.



산술적 시프트 연산의 설명을 종합해보면 양수이건 음수이건 상관없이 좌측 시프트 연산은 원래 데이터에 2를 곱하는 결과를, 우측 시프트 연산은 원래 데이터를 2로 나눈 결과가 된다는 점이다.


## 5. 정수 연산 ##

1) 덧셈

두 수를 더하면 된다. 여기서 올림수(carry)가 발생하여 새로운 자리의 비트가 생성되면 버리면 된다.

ex1) -4 + 5
1100
+0101
10001 -> carry 날리면 0001 = 1

ex2) -100+45
10011100
+00101101
11001001 = -55

이처럼 덧셈을 수행하는 하드웨어 유닛을 병렬 가산기(parallel adder)라고 부른다. 가산기에는 반가산기(half adder)와 전가산기(full adder)가 있다. 병렬 가산기는 전가산기를 병렬로 연결한 모듈이다. n개의 전가산기를 병렬로 연결한 병렬 가산기는 n자리 이진수 사이의 덧셈을 수행할 수 있다.

parallel_adder

병렬 가산기에서 올림수 비트(carry bit)는 상위 전가산기로 전송된다.

2진 데이터 (A4A3A2A1)과 (B4B3B2B1)을 더하여 나온 결과는 S4S3S2S1으로 출력된다.

덧셈의 결과와 관련된 정보를 저장해주는 상태 레지스터에는 아래와같은 플래그들이 포함되어 있다.

S : 부호 플래그. 최상위 비트(MSB)를 저장한다. 따라서 양수면 0, 음수면 1이 된다. 즉, 덧셈 결과가 음수면 SET이 된다.

C : 올림수 플래그. 최상위 단계의 전가산기에서 올림수가 발생하면 SET된다.

Z : 제로(Zero) 플래그. 덧셈결과 각각의 비트가 NOR 게이트를 통과한다. 모든 비트가 0인 경우에만 1이 되므로 덧셈결과가 0이면 Z플래그가 SET이 된다.

V : 오버플로(overflow) 플래그. 가장 최상위 두 단계의 전가산기의 올림수(위 그림에서는 C4와 C3)가 다르다는 것은 두 수의 덧셈 결과가 비트의 표현 범위를 초과하게 되었다는 것이다. C4와 C3의 값이 XOR 게이트를 통과하므로 두 값이 다르면 V값이 SET된다.

ex) 오버플로 예제

4bit로 표현되는 두 수 8과 9를 덧셈해보자.

1000
+1001
10001 -> 올림수 버리면 0001 = 1

2의 보수 표현법에서 4비트가 표현 가능한 범위는 -8 ~ +7 이다.



2) 뺄셈

뺄셈을 위한 회로는 따로 없다. 예를들어 A에서 B를 빼야하는 경우(A-B)에는 B를 2의 보수화 시켜서 더하면 된다. 논리적으로는 A-B = A+(-B)이다. 물론 덧셈과 마찬가지로 최상위비트에서 발생하는 올림수는 버린다.



3) 곱셈

a) 부호 없는 정수의 곱셈

곱셈은 컴퓨터 입장에서 꽤 복잡한 연산이다. 2의 보수로 표현되는 정수의 곱셈을 보기 전 부호 없는 정수간의 곱셈부터 살펴본다.

unsigned_integer_multiply

승수의 각 비트들에 대해 차례대로 곱셈이 수행되고 피승수에 더해진다. 더해진 부분적들은 오른쪽으로 shift하여 새로 나온 부분적과 자릿수를 맞춘다.

컴퓨터에서는 위 계산을 병렬 가산기를 사용하여 수행한다. 승수 비트가 1이면 피승수를 현재까지의 누적 부분적에 더하고, 0이면 더하지 않으면 된다. 왜냐하면 2진수에서는 모든 비트가 0 혹은 1이기 때문이다. 이 과정을 수행하는 하드웨어 구성도는 아래 그림과 같다.

unsigned_integer_multiply_hardware

레지스터 C와 A, 그리고 Q는 논리적으로 하나의 레지스터로 본다. 계산이 수행될때마다 오른쪽으로 1번씩 shift 연산을 하고 최종적으로 C-A-Q에 저장된 비트들이 곱셈 결과이다.

초기에는 C와 A는 0으로 채워진다. 그리고 Q에는 승수로 초기화되어있다. 또한 M에 피승수가 저장되어있다.

매번 연산이 수행될 때 Q의 최하위비트 Q0비트가 1이면 M레지스터의 피승수와 A레지스터의 중간결과가 더해지고, 0이면 더해지지 않는다. 만약 올림수가 발생하면 레지스터 C에 저장된다. 이후에 C-A-Q에서 오른쪽으로 shift연산이 이루어진다. Q레지스터의 최하위비트는 곱셈에 사용되었으므로 버려진다.

위 예제의 계산이 진행됨에따라 위 그림 하드웨어의 레지스터들 값의 상태변화는 아래 실행도와 같다.

unsigned_integer_multiply_flow



b) 2의 보수의 곱셈

2의 보수의 곱셈을 위해서는 부호 없는 정수의 곱셈을 위한 하드웨어에 추가적인 모듈이 필요하다.

  • 피승수를 저장하는 레지스터 M과 병렬 가산기 사이에 보수기(complementer)가 추가된다.
  • Q레지스터의 오른쪽에 1비트짜리 Q-1 레지스터가 추가된다. Q0 레지스터와 함께 Q-1 레지스터의 값이 제어회로에 입력된다.


2의 보수 곱셈을 컴퓨터를 통해 하는 과정은 상당히 난해하다. 가장 널리 쓰이는 알고리즘이 Booth 알고리즘인데, 알고리즘의 흐름도는 아래와 같다.

booth_algorithm_flowchart



4) 나눗셈

나눗셈에서도 곱셈과 마찬가지로 반복적인 뺄셈과 시프트 연산으로 수행된다.

unsigned_integer_divide

위 그림은 부호없는 나눗셈 과정이다. 일반적인 나눗셈 과정을 생각해보면 피제수의 비트를 하나씩 내리면서 제수보다 커질 경우 제수를 빼고 부분 나머지를 획득한다. 여기에 피제수의 남은 비트들을 하나씩 이어붙이면서 제수보다 커지면 제수를 빼고 부분 나머지를 획득한다. 이 과정의 반복이다. 다만 곱셈 연산과 다른 점은 시프트연산이 좌측으로 일어난다는 점이다. 이것은 나눗셈의 계산과정과 관련있다. 피제수에서 상위 비트부터 아래로 내려가면서 제수를 빼줄수 있는지 탐색하기 때문이다.

위 알고리즘의 흐름도는 아래 그림과 같다.

unsigned_integer_divide_flowchart

부분 나머지는 레지스터 A에 저장된다. 또한 몫은 레지스터 Q의 최하위비트(Q0)에 한 사이클당 하나씩 채워진다. 그리고 시프트 연산이 수행되는 과정들이 반복되면 최후에 레지스터 Q에는 몫이, A에는 최종 나머지가 저장되어있다.

특이하게도 피제수를 뺄 수 있는지 체크를 하지않고 부분나머지 A에서 제수 M을 일단 뺀다. 이후 빼는 행위가 정당했다면 A는 0보다 크거나 같을 것이다. 0보다 작다면 몫에 Q0에 0을 넣고 A에 M을 다시 더한다.

2의 보수의 나눗셈은 위의 알고리즘을 약간 고치면 된다.


지금까지 정수의 4칙연산에 대해 다루었다. 덧셈과 뺄셈은 병렬 가산기에 의해 수행된다. 곱셈과 나눗셈은 알고리즘이 상당히 복잡하다. 그러나 핵심 포인트는 병렬 가산기와 시프트연산의 반복 수행이란 점이다. 실제 곱셈이나 나눗셈 연산을 한 비트씩 진행하면서 중간 결과들을 레지스터에 저장하는 동작이 반복적으로 일어난다는 점이 중요하다. 그 결과로 컴퓨터 입장에서 덧셈과 나눗셈보다는 곱셈, 나눗셈의 연산에 더 많은 자원이 소모된다는 점이 중요하다.


## 6. 부동소수점 표현방식 ##



1) 부동소수점 표현방식

정수의 2진수 표현방법으로도 소수를 표현할 방법이 있지만 표현범위의 한계가 너무 작아 비효율적이다. 과학적 표기의 가수, 지수 개념을 응용하여 표현가능범위를 크게 늘린 방식이 부동소수점(floating-point) 표현 방식이다.

부동소수점의 일반식은 아래와 같다.

floating_point_general_equation

S : 부호(sign)
M : 가수(mantissa)
B : 기수(base)
E : 지수(exponent)

예를들어 10진 부동소수점 수 3.48 * 10^21에서 S=0, M=3.48, B=10, E=21이다.

10진 부동소수점수에서 B는 10이고, 2진 부동소수점의경우 B는 2로 암묵적 약속이 되어있어 실제 표현에서는 B를위한 비트는 할당되지 않는다. 컴퓨터가 사용하는 방식은 2진 부동소수점 방식으로 모든 수가 0 혹은 1이다.

2진 부동소수점 수에는 32비트 혹은 64비트가 표현형식이 있다. 아래 그림은 전형적인 32비트 2진 부동소수점 수의 형식이다.

32bit_floating_point_representation

가수 M에 할당된 비트수가 클수록 수를 더욱 정밀하게 표현할 수 있으며, 지수 E에 할당된 범위가 클수록 표현가능 범위가 늘어난다. 하나를 위해 더 많은 비트수를 할당하면 다른 하나는 줄어들기때문에 적절한 범위 조절이 필요하다.

위 그림에서 지수 필드는 8비트를 사용하므로 -2^7 ~ +2^7-1의 범위를 표현할 수 있다. 또한 가수 필드는 23비트를 사용하므로 2^-23의 정밀도까지 수를 표현할 수 있다.



2) 정규화 표현

부동소수점 표현에서는 아래와 같이 하나의 같은수를 위한 여러개의 표현이 존재할 수 있다.

0.1101 * 2^5 = 11.01 * 2^3 = 0.001101 * 2^7

위 수들은 모두 동일하다. 혼란을 막기위해 부동소수점 표현에서는 정규화 표현(normalized representation)을 사용한다.

정수 부분은 0이며, 소숫점 첫째 자리는 1이 되도록 지수 E를 고정한 표현방식이 정규화 표현이다. 위 3개의 수들 중 정규화표현에 해당하는 수는 0.1101 * 2^5이다. 여기서 0.1bbb의 형태를 만들기위해 지수 E는 5로 고정되었다.

그럼 0.1101 * 2^5의 예를 32비트 지금까지 설명한 부동소수점 형식으로 표현해보자.

부동소수점 표현에서 정수부분 0은 표현할 필요가 없다.

가수필드(M) 1101 0000 0000 0000 0000 000 이 된다.

지수필드(E) 0000 0101

부호필드(S) 0

단순히 각각의 필드에 해당 수를 넣어주면 된다. 그러나 실제로는 여러가지 문제점때문에 이러한 방식을 사용하지 않는다. 위 부동소수점 표현에 2가지 변화가 추가된다. 이 2가지 변화를 설명한 후 그 문제점이 무엇이고 아래의 방법이 어떻게 해결을 하는지 설명한다.

a) 바이어스(bias)

지수 필드는 그대로 사용되지 않는다. 지수 필드의 비트는 실제 지수에 +128(1000 0000)을 더한 값이다.

예를들어 0.1101 * 2^5에서는 지수필드가 5(0000 0101) 이었지만 실제 컴퓨터는 여기에 +128(1000 0000)을 더한 (1000 0101)을 사용한다. 즉, 실제 지수필드 값이 +128 바이어스되어 사용된다.

바이어스는 기준점 정도로 생각하면 된다. 비슷한 예로 우리가 사용하는 모든 전압 표현은 땅의 전압을 기준으로 바이어스된 전압인 것과 마찬가지이다. 즉, 5V라고 말하는 표현은 지구 땅의 전압보다 5V가 높다는 것이다.

반대로 실제 지수 필드를 구할때는 지수 비트에서 128(1000 0000)을 빼서 구한다.

결과를 정리하자면 0000 0000(-128)부터 1111 1111(+127)까지가 있다.

이렇게 했을때 해결되는 문제점은 0-비트 검사 문제이다. 기존 방식에서는 0을 표현할 때 가수(M)만 0이 된다면 지수필드 E는 어떤 값이 되어도 상관없었다. 그러나 바이어스를 사용하면 가수가 0이고 지수필드가 0일 때 지수가 -127이 되고 이는 0에 매우 근접한 수이다. 여기서 중요한 점은 이 때 모든 비트가 0이 된다는 점이고 CPU가 쉽게 0비트 검사를 할 수가 있다.

b)첫 번째 소수점은 표현하지 않는다

정규화 표현에서의 약속은 0.1bbbbb * 2^E 형태였다. 첫 번째 소숫점은 항상 1로 고정되므로 처리할 때 이를 따져주기만 하면 된다. 따라서 가수 필드에서는 첫 번째 소수점의 1은 표시하지 않기 때문에 1비트를 추가적으로 사용할 수 있게 된다.


위 두 가지 변화사항을 적용하여 새로이 0.1101 *2^5의 32비트 부동소수점 필드값들을 계산해보자.

가수필드(M) : 첫 번째 소수점은 넣지 않으므로 1010 0000 0000 0000 0000 000

지수필드(E) : 실제 지수 5(0000 0101)에 128(1000 0000)을 더한 1000 0101

부호 필드(S) : 0


위 결과들을 종합했을 때 32비트 부동소수점 표현방식이 나타낼 수 있는 수의 표현범위는 아래 그림과 같다.

floating_point_representation_range

양수를 기준으로 가장 작은 수는 먼저 가수의 0.1bbbbb 부분에서 모든 b가 0이 될 경우, 즉 0.5이다. 또한 지수는 -128 ~ +128 범위를 가지므로 지수는 -128인 경우이다. 즉, 0.5 * 2^-128이 나타낼 수 있는 가장 작은 수이다.

가장 큰 수는 모든 가수가 1이 되는 경우에는 모든 23비트의 가수필드가 1이 되고 지수가 127이 되는경우, 즉 (1/2 + 1/4 + 1/8 + … + 2^-24) * 2^127 이다.

위 그림에서 절대값이 아무리 작아도 0으로는 근접할 수 없기 때문에 언더플로우가 존재한다. 또한 범위를 넘어가는 경우에는 오버플로우가 발생한다.



3) IEEE 754 부동소수점 표현 형식

미국 전기전자공학회(IEEE)에서는 가수부를 0.1bbbb 형식이 아닌 1.M 형식을 사용한다. 또한 바이어스를 128이 아닌 127(0111 1111)을 사용한다.

따라서 부호필드 비트가 S, 가수필드 비트가 M, 지수필드 비트가 E라면 실수 N = (-1)^S * (1.M) * 2^(E-127)이 된다.

-1101.101 = -1.101101 * 2^3; [1][0000 0011][1011 0100 0000 0000 0000 000]

00000011
01111111
10000010


## 7. 부동소수점 연산 ##



1) 덧셈과 뺄셈

덧셈과 뺄셈을 할때는 지수부를 일치시켜야 한다. 자릿수를 맞추는 것이다.

floating_point_addition

부동소수점의 덧셈 과정을 정리하면 아래와 같다.

a) 소수점 위치가 같아지도록 지수를 일치시킨다.
b) 가수들간의 덧셈을 수행한다.
c) 결과를 정규화시킨다.

소수점 위치가 같아지도록 조정하는 과정은 가수부를 오른쪽으로 쉬프트 시키고 한 번의 쉬프트연산마다 지수를 1씩 증가시키는 것이다. 이 과정을 두 수의 지수가 같아질때까지 하면 된다.

지수값을 일치시킬 때 더 작은 지수의 값을 더 큰 지수로 맞추어 주는것이 좋다. 그래야 버려지는 비트가 발생하더라도 잃게되는 수의 절대크기가 상대적으로 작은 값이 되기때문에 오차범위가 줄어든다.

빼기 과정은 감수(빼지는 수)를 2의 보수를 취한후에 덧셈과정을 진행하면 된다.



2) 곱셈과 나눗셈

곱셈과 나눗셈은 지수부 일치가 필요하지 않기때문에 덧셈 과정보다 간단하다. 2진 부동소수점의 곱셈 과정은 아래의 단계들로 이루어진다.

a) 가수끼리 곱한다.
b) 지수끼리 더한다. 바이어스도 두 번 더해진것이므로 바이어스를 뺀다.
c) 결과를 정규화한다.

아래 그림은 위 과정을 수행하는 예제이다.

floating_point_multiplication



나눗셈의 경우에는 가수끼리 나누고 지수끼리 빼면 된다는 점만 다르고 나머지는 곱셈 과정과 동일하다.



부동 소수점의 4칙연산 과정에서는 오버플로우 문제가 발생할 수 있다. 예를들어 곱셈 과정에서 지수끼리 더했는데 표현할 수 있는 범위를 넘어서는 경우 엉뚱한 값이 저장된다. 혹은 덧셈 과정에서 소수점 위치를 맞추기 위해 더 작은수의 가수를 쉬프트 시키는 과정에서 버려지는 수가 발생하게 될 수도 있는데, 이 때는 반올림이나 버림 과정이 진행된다. 이 때는 버려지는 비트 자릿수가 MSB에 비해 절대적 크기가 작은 경우에는 크게 문제가 되지 않으므로 지수 오버플로우보다는 그 영향력이 덜하다고 할 수 있다.

+ Recent posts