Computer Architecture/CS APP

[CS] 부동 소수점 (Floating Point)

  • -

실수를 표현하는 방식으로 꽤 많은 종류의 형태가 제안되었지만, 현재까지 가장 많이 사용하는 방식은 IEEE 표준 754 부동 소수점 표현이다.

 

십진수 표기법

 

 

이진수 표기법 (비트)

 

 

이진수 표기법의 한계

  • 0.2 같은 경우에는 이진수 표기법으로 정확하게 표기가 불가능하다.

 

  • 매우 큰 수를 표현하기에 부적합하다
    : 예를 들어 5 * 2^100은 101000000000…. (0이 100개 필요)

 

 

IEEE 부동소수점

 

  1. S는 숫자가 음수인지 양수인지 결정, 해당 비트는 MSB(Most Significant Bit) 처리
  2. M은 분수 이진수 (가수부)
  3. E는 2의 거듭제곱인 가중치

 

  • 단정밀도 (float) : 앞 8비트 = 지수, 뒤 23비트 = 분수
  • 배정밀도 (double) : 앞 11비트 = 지수, 뒤 52비트 = 분수

지수의 범위는 단정밀도의 경우 -126 ~ +127, 배정밀도의 경우 -1022 ~ +1023가 됨

 

 

Bias

 

(n은 지수의 비트 개수)

  • 64비트: 지수 11비트, 2^10 = 1024, 1024 - 1 = 1023
  • 32비트: 지수 8비트, 2^7=128, 128 - 1 = 127

 

 

지수부의 변형

  1. 정규화된 값
    : 지수의 비트가 모두 0도 아니고 1도 아닐 때, 지수 = 지수 - Bias

  2. 비정규화된 값
    : 지수의 비트가 모두 0인 경우, 지수 = 1 - Bias
    • 기능 1
      - 정규화된 숫자를 사용하면 항상 M이 1 이상이어야 하므로 0을 나타낼 수 없기 때문에 숫자 값 0을 나타낼 수 있는 방법을 제공
      - 실제로 +0.0의 부동 소수점 표현은 부호 비트가 0이고 지수 필드가 모두 0(비정규화된 값을 나타냄)인 등 모두 0으로 이루어진 비트 패턴을 가짐
    • 기능 2
      0.0에 매우 가까운 숫자를 표현하는 것. 가능한 숫자 값이 0.0에 가깝게 균등하게 배치되는 점진적 언더플로라는 속성을 제공
  3. 특별한 값
    : 지수 비트가 모두 1인 경우
    • 분수 비트가 모두 0인 경우 infinity (부호에 따라 +-)
      : 두 개의 매우 큰 숫자를 곱하거나, 0으로 나눌 때 등 넘쳐나는 값을 표현할 때 사용
    • 분수 비트가 모두 0이 아닌 경우 NaN (Not a Number)
      : 이러한 값은 √-1 또는 ∞-∞를 계산할 때처럼 결과를 실수 또는 무한대로 제공할 수 없을 때 사용

 

 

간단한 예를 통한 이해

: -9.6875를 부동소수점 비트로 나타내보자.

  1. 9.6875를 이진법으로 나타내면 -1001.1011 (고정 소수점)
    : 정수부인 9는 1001로, 소수부인 0.6875는 위의 이진수 표기법으로 0.1011
  2. 지수의 비트가 모두 0도 아니고 1도 아니기 때문에 정규화를 거침
    : 1001.1011 의 맨 앞 비트만 정수로 놔두면 -1.0011011 * 2^3, 지수부는 2^3, 가수부는 0011011
  3. 지수를 그냥 사용하지는 않고 Bias 표기법을 사용함
    : 이유는 순수한 0을 표기하기 위해서,
    일반적으로 변수를 초기화 할 때 모든 비트를 0으로 설정하는 것이나
    지수를 이진수 표기법으로 두고 float을 0으로 다 채우게 되면 2^0을 뜻해서 값이 1이 됨

이진수 표기 계산법

 

(0이 될 때까지 2를 곱하며 몫을 취함, 딱 떨어지지 않으면 무한 반복, 적당한 자릿수 취함)

 

 

  • MSB = 음수라서 1
  • M = 구한 가수부를 왼쪽부터 채워넣기. 나머지는 0
  • E = 현재 지수부 비트가 모두 1도 0도 아니므로 정규화 과정이 필요,
    지수 = 지수 - Bias이므로 E = 3(0000 0011) - 127(0111 1111) = 10000010

 

 

부동 소수점의 표현 한계

: 지수가 23 이상인 경우 (float)

10000000000000000000000 → 정규화 시키면 소숫점이 왼쪽으로 23번 움직임
그럼 마지막 0 뒤에 있던 비트는 사라지게 됨, float의 가수부는 23비트이기 때문
그 값이 8,388,608 이며 이 수부터는 소숫점을 표기할 수 없게 됨.

 

 

근사법

  1. 짝수 근사법
    : 가까운 값으로 반올림되며, 정확히 중간 값은 결과값이 짝수가 되도록 함
    → 어떤 데이터 집합을 근사했을 때 한 쪽으로 치우쳐지지 않는 장점을 가짐
  2. 영방향 근사법
    : 양수 값은 아래쪽으로, 음수 값은 위쪽으로 0에 가까이..
  3. 하향 근사법.
    : 양수와 음수를 모두 아래쪽으로 근사
  4. 상향 근사법
    : 양수와 음수를 모두 위쪽으로 근사부동소수점 연산

 

 

부동 소수점 연산

: 부동소수점은 제한된 범위와 정밀도를 갖기 때문에 실제 연산의 근사값을 사용할 수밖에 없다.

  • 특수 경우
    • 1 / -0 = -inf
    • 1 / +0 = +inf
    • +inf -inf = NaN
  • 덧셈, 곱셈에서 교환법칙은 성립하나 결합, 분배법칙은 성립하지 않음
  • 곱셈은 근사하는 과정에서 손실이나 오버플로우 가능성 때문임

 

 

참고

https://dataonair.or.kr/db-tech-reference/d-lounge/expert-column/?mod=document&uid=52381

 

C++프로그래밍 : 부동소수점 구조와 원리

C++프로그래밍 부동소수점 구조와 원리 C/C++, 자바(Java)와 같은 프로그래밍 언어에서는 수를 표현하기 위해 크게 두 가지 타입을 제공한다. 바로 정수 타입과, 부동소수점 타입이다. 수학 교과 과

dataonair.or.kr

 

『Computer Systems: A Programmer's Perspective』 책을 읽고 정리한 글입니다.
검색을 허용하지 않고, 수익을 창출하지 않습니다.
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.