CS

[컴퓨터 구조] chapter3 정리(컴퓨터 연산 : 부동소수점)

SeungbeomKim 2023. 5. 28. 22:25

오늘은 부동 소수점에 대해서 알아보겠습니다.

부동소수점(=떠돌이 소수점 방식)은 실수를 컴퓨터 상에서 근사하여 표현할 때 소수점의 위치를 고정하지 않고, 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수를 나누어 표현합니다.

(컴퓨터에서 소수점 이하의 값을 가지는 실수를 표현하는 방법)

https://ko.wikipedia.org/wiki/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90

 

부동소수점 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 초기의 전기기계식 프로그래밍 가능한 컴퓨터 Z3에는 부동소수점 산술 기능이 포함되었다. (뮌헨의 국립 독일 박물관) 부동소수점(浮動小數點, floating point) 또

ko.wikipedia.org

부동 소수점의 표현 수준

IEEE Std 754-1985

  • IEEE(전지전자공학자협회)에서 1985년에 표준으로 채택

표현 방식의 다양성을 해결하고자 제안됨

  • ex) 0.10100 * 2^3, 0.01010* 2^4
  • 수 표기의 호환성 증대
  • 1980년 이후 컴퓨터는 거의 모두 따르는 수준

표현방식

  • 단일 정밀도 (Single precision, 32-bit)
  • 2배 정밀도 (Double precision, 64-bit)

고정 소수점 표현형식 = (부호와 크기 표현방식, sign and magnitude)

  • 정수 부분과 실수 부분의 자릿수를 고정
  • 부호비트와, 각각을 나타내는 비트를 사전적으로 할당
  • ex) 7.625

부호비트 : 0 (양수), 정수부 : 7(111), 소수부 : 0.625(10100000)

  • 구현은 편하지만, 표현 가능한 수의 범위와 정밀도가 낮아 거의 사용되지 않음
  • 이를 부동 소수점 표현방식으로 바꿔주면, 111.101 = 1.11101 * 2^2 이므로, 지수부는 10(2)을 나타내고, 가수부는 111101(2)을 나타냄

 

단일 정밀도(32) vs 2배 정밀도(64)

단일 정밀도 : 32비트 표현 (부호 1, 지수 8, 가수 23)

2배 정밀도 : 64비트 표현(부호 1, 지수 11, 가수 52)

 

  • S : 부호 비트(0-> Positive, 1 -> Negative)
  • 정규화된 유효자리 (significand) : 1.0 <= |유효자리| < 2.0 : 항상 1로 시작하기에, 1을 비트로는 표현 x(잠복 비트)
  • 지수 : Exponent - Bias 
    • Exponent는 부호 없는 수
    • 000...000 가장 작고, 111...111이 가장 큰 수 
    • 음수를 나타내기 위해 Bias를 뺌
    • 단일 정밀도 : Bias = 127 2배 정밀도 : Bias = 1203

지수필드가 모두 0이거나 모두 1인 경우는 다른 수를 표현하는 데 사용하기 위함

  • 00000000은 잠복비트가 없음을 나타냄 (0.xxxx)
    • 지수는 1-Bias이고, 가수는 0.f
    • 가수필드가 00000이라면, 전체 수는 0을 나타낼 수 있음
  • 11111111인 경우 
    • 가수 필드가 모두 0이면 무한대 (혹은 - 무한대)
    • 가수필드가 모두 0이 아니면 NaN(Not a Number)

 

지수필드가 00000000, 11111111 사이의 수일 때,

 

가장 작은 수

  • 지수 필드 : 00000001 -> 실제 지수 = 1 - 127 = -126
  • 가수 필드 : 000...000 -> 유효자리 = 1.0
  • ±1.0 * 2^-126

가장 큰 수

  • 지수 필드 : 11111110 -> 실제 지수 = 254 - 127 = 127
  • 가수 필드 : 111...111 -> 유효자리 ≒ 2.0
  • ±2.0 * 2^127

2배 정밀도 비트도 같은 맥락으로 위에화 비슷하게 계산할 수 있습니다. (지수 부분은 Bias가 127이 아닌 1023을 빼줘야 합니다)

 

오버플로 vs 언더플로

  • 오버플로
    • 주어진 표현방식의 범위가 작아 표현할 수 없는 경우(심각한 오류)
    • 단일 정밀도 표현에서 1.0*2^130 표현 (2^127)까지 표현이 가능한데 범위를 초과한 경우
  • 언더플로
    • 주어진 표현방식의 정확도가 떨어져서 소수 부분을 정확히 표현할 수 없는 경우(심각한 오류 X)

실수 -> 부동 소수점으로 표현 

 

-0.75 = (-1)^1 * 1.1(2) * 2^-1 

  • 부호비트 : 1
  • 가수필드 : 100...000(2)
  • 지수필드 : -1 + Bias = -1 + 126 = 01111110(2) (단일 정밀도), -1 + 1023 = 1022 = 01111111110(2) (2배 정밀도)
  • 단일 정밀도 : 1011111101000...00
  • 2배 정밀도 : 1011111111101000..00

 

부동 소수점 -> 실수로 표현

11000000101000..00

  • 부호비트 : 1
  • 가수필드 : 01000...00(2)
  • 지수필드 : 10000001(2)=129
  • X = (-1)^1 * (1 + 01(2)) * 2^(129-127) = -1 * 1.25(0*2^-1+1*2^-2)*2^2 = -5.0

 

부동소수점 덧셈

4-digit 10진수 example (9.999 * 10^1 + 1.610 * 10^-1)

  1. 소수점을 맞춘 후, 더 작은 지수의 수를 더 큰 지수의 수에 맞게 Shift 해줍니다 (9.999 * 10^1 + 0.016 ^ 10^1)
  2. 유효숫자를 더합니다 (10.015 * 10^1)
  3. 정규화(정수부를 1로 맞추고, 적절하게 소수점 위치 조정)하고, 오버플로/언더플로 검사 (1.0015 * 10^2)
  4. 필요하다면 반올림하고 다시 정규화, 오버플로/언더플로 검사 (1.002 * 10^2)

4-digit 2진수 example (1.000(2) * 2^-1 + -1.110(2) * 2^-2 = 0.5 + 0.4375)

  1. 소수점을 맞춘 후, 더 작은 지수의 수를 더 큰 지수의 수에 맞게 Shift 해줍니다 (1.000* 2^-1 + -0.111 * 2^-1)
  2. 유효숫자를 더합니다 (0.001 * 2^-1, 2의 보수 연산 진행)
  3. 정규화(정수부를 1로 맞추고, 적절하게 소수점 위치 조정)하고, 오버플로/언더플로 검사 (1.000 * 2^-4)
  4. 필요하다면 반올림하고 다시 정규화, 오버플로/언더플로 검사 (1.002 * 10^2 = 0.0625)

부동소수점 덧셈기 하드웨어

  • 정수 덧셈보다 훨씬 복잡하며, 한 클럭 사이클동안 이루어지기엔 너무 과정이 깁니다.
  • 부동소수점 덧셈기는 여러 클럭 사이클로 이루어집니다(파이프라인화 될 수 있음)

부동소수점 덧셈기 하드웨어

 

  • Step1
    • 어느 지수가 더 큰지를 비교하기 위해 Small ALU(산술논리연산장치)에서 두 개의 지수를 빼줍니다.
    • 여기에서 나온 지수 차이를 통해 제어신호는 3개의 멀티플렉서를 제어해 줍니다(가장 왼쪽 멀티플렉서 : 큰 지수 선택, 중앙 멀티플렉서 : 작은 수의 유효자리 선택, 가장 오른쪽 멀티플렉서 : 큰 수의 유효자리 선택)
  • Step2 
    • 작은 유효자리가 오른쪽으로 이동하고, 정규화 이전에, Big ALU를 통해 값들을 더해줍니다. 
  • Step3
    • Big ALU에 의해 더해진 값들을 왼쪽이나 오른쪽으로 자리이동 시키고, 지수를 증가하고 감소시킵니다.
  • Step4
    • 자리맞춤 단계(Round)에서 최종 결과가 나오게 됩니다.

MIPS의 부동 소수점 명령어 (single, double)

부동 소수점 연산은 보조프로세서를 활용하면서, 부동소수점 레지스터에서만 동작합니다.

  • 단일 정밀도 : add.s, sub.s, mul.s, div.s, c.x.s, lwc1(적재), swc1(저장)
  • 2배 정밀도 : add.d, sub.d, mul.d, div.d, c.x.d, 1dc1(적재), sdc1(저장)
  • 여기에서 x는 equal(eq), not equal(neq), less than(lt), less than or equal(le), greater than(ht), greater than or equal(ge)가 될 수 있습니다.
  • c.x.s -> 비교 조건에 따라서 상태를 나타내는 cond 비트를 참 또는 거짓으로 만듭니다.
  • bc1t(참일 때 분기), bc1f(거짓일 때 분기)

ex) ˚F To ˚C (화씨 -> 섭씨)

 

 C code 

float f2c (float fahrenheit) {
	return ((5.0/9.0)*(fahr - 32.0));
}

MIPS code ($gp(global pointer 적용, 정적 데이터를 위한 전역 포인터))

f2c : lwc1   $f16, const5($gp)
      lwc2   $f18, const9($gp)
      div.s  $f16, $f16, $f18
      lwc1   $f18, const32($gp)
      sub.s  $f18, $f12, $f18
      mul.s  $f0,  $f16, $g18
      jr     $ra

 

컴퓨터에서 실수를 표현하기 위한 부동소수점과 MIPS 부동소수점 명령에 대해 알아볼 수 있었습니다. 그리고 유동적으로 실수 값을 부동 소수점으로 바꿔보고, 부동소수점에서 실수로 변환하는 과정에 대해서도 공부할 수 있었습니다.