IEEE 부동 소수점 오류의 이해를 위한 자습서

기술 자료 번역 기술 자료 번역
기술 자료: 42980 - 이 문서가 적용되는 제품 보기.
이 문서는 이전에 다음 ID로 출판되었음: KR42980
모두 확대 | 모두 축소

이 페이지에서

요약

부동 소수점 연산은 많은 프로그래머가 혼동하는 어려운 개념입니다. 다음 자습서는 부동 소수점 오류가 발생할 가능성이 있는 프로그래밍 상황과 이를 예방하는 방법을 이해하는 데 유용합니다. 또한 실제 컴파일러 버그와 달리 근본적인 부동 소수점 연산 제한으로 인한 사례를 이해할 수도 있습니다.

추가 정보

십진수 및 이진수 체계

일반적으로 10을 기수로 수를 셉니다. 기수는 임의적인 것입니다. 전통적으로 기수 10을 사용하게 된 이유는 단지 수를 세는 데 편리하게 이용했던 도구인 손가락이 10개이기 때문입니다.

십진수 532.25(기수 10)는 다음을 의미합니다.
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
       500    +     30     +      2     +     2/10    +    5/100
   _________
   =  532.25

이진수 시스템(기수 2)에서 각 열은 10 대신 2의 제곱을 나타냅니다. 예를 들어 101.01의 수는 다음을 의미합니다.
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
       4     +      0    +     1     +      0     +    1/4
   _________
   =  5.25  십진수

PC에서 정수를 표현하는 방법

정수에는 소수부가 없기 때문에 부동 소수점 값보다 시스템 표현이 훨씬 간단합니다. PC에서 일반 정수는 부호를 나타내는 가장 중요한 비트를 포함하여 2바이트(16비트) 길이입니다. 긴 정수는 4바이트 길이입니다. 양수는 간단한 이진수입니다. 예를 들면 다음과 같습니다.
    십진수 1 = 이진수 1
    십진수 2 = 이진수 10
   십진수 22 = 이진수 10110 등

그러나 음수는 2의 보수 체계를 사용하여 표현됩니다. 음수에 대한 2의 보수 표현을 얻으려면 수의 절대값에 대한 이진 표현을 구한 다음 모든 비트를 뒤집고 1을 추가합니다. 예를 들면 다음과 같습니다.
   십진수 4 = 0000 0000 0000 0100
               1111 1111 1111 1011     비트를 뒤집습니다
   -4        = 1111 1111 1111 1100     1을 추가합니다

십진수 -1은 이진수 1111 1111 1111 1111이며 따라서 Basic이 -1을 논리 참(모든 비트 = 1)으로 간주합니다. 이것은 비트 단위나 논리 비교를 위한 별도의 연산자가 없기 때문에 발생한 것입니다. Basic에서 프로그램이 많은 논리 비교를 할 때는 대부분 아래의 코드를 사용하는 것이 편리합니다. 이렇게 하면 훨씬 읽기가 쉬워집니다.
   CONST TRUE = -1
   CONST FALSE = NOT TRUE

일반 이진 산술을 사용하여 2의 보수 조합을 모두 더하면 올바른 결과가 산출됩니다.

부동 소수점의 복잡성

모든 십진 정수는 이진 정수로 정확하게 표현할 수 있지만 분수의 경우에는 그렇지 못합니다. 사실 기수가 10인 모든 무리수는 10 이하의 기수를 가진 모든 시스템에서도 무리수가 됩니다.

특히 이진수의 경우 p/q의 형태로 표현할 수 있는 분수(여기서 q는 2의 정수 제곱)만이 비트의 무한수로 정확히 표현할 수 있습니다.

10진수 0.0001과 같은 일반적인 소수는 이진수로 정확하게 표현할 수 없습니다. 0.0001은 104비트 주기로 반복되는 이진 순환 소수입니다.

아래와 같은 간단한 예를 통하여 이러한 이유를 알 수 있습니다.
   SUM = 0
   FOR I% = 1 TO 10000
      SUM = SUM + 0.0001
   NEXT I%
   PRINT SUM                   ' Theoretically = 1.0.

출력으로 1.000054가 표시됩니다. 이진수로 0.0001의 작은 오류가 합계에 전파됩니다.

같은 이유로 실수를 비교할 때는 항상 주의해야 합니다. 다음 예는 일반적인 프로그래밍 오류를 보여줍니다.
   item1# = 69.82#
   item2# = 69.20# + 0.62#
   IF item1# = item2# then print "Equality!"

여기서는 값이 수식에서 생성된 값과는 약간 다르게(이진수로) 할당되도록 하여 69.82를 이진수로 정확히 표현할 수 없기 때문에 "Equality!"가 인쇄되지 않습니다. 실제로 이런 비교에서는 항상 약간의 내결함성을 허용하도록 코딩해야 합니다. 예를 들면 다음과 같습니다.
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"

이렇게 하면 "Equal"이 인쇄됩니다.

IEEE 형식 숫자

MS-DOS용 QuickBasic 버전 3.0은 수치 연산 보조 프로세서가 있는 시스템용으로 MBF(Microsoft Binary Floating Point) 버전과 IEEE(Institute of Electrical and Electronics Engineers) 버전이 함께 출시되었습니다. MS-DOS용 QuickBasic 버전 4.0 이상만 IEEE를 사용합니다. Microsoft는 다음 세 가지 이유로 Basic의 최신 버전에서 부동 소수점 값을 표현하기 위해 IEEE 표준을 선택했습니다.
  1. Basic이 IEEE 형식을 사용하는 Intel 수치 연산 보조 프로세서를 사용할 수 있도록 하기 위해서입니다. Intel 80x87 시리즈 보조 프로세서는 Microsoft 이진 형식 숫자를 처리할 수 없습니다.
  2. Basic, C, Pascal, FORTRAN 및 MASM 간에 언어 상호 호출을 훨씬 쉽게 하기 위해서입니다. 그렇지 않으면 언어 간에 숫자 값을 보내는데 변환 루틴을 사용해야 합니다.
  3. 일관성을 얻기 위해서입니다. IEEE는 C와 FORTRAN 컴파일러에 대한 승인된 업계 표준입니다.
다음은 배정밀도 숫자에 대한 IEEE와 MBF 표현을 간단히 비교한 것입니다.
               부호 비트   지수 비트         가수 비트
               ---------   -------------   -------------
   IEEE        1           11              52 + 1(암시적)
    MBF        1            8              56

IEEE와 MBF 부동 소수점 표현 간의 차이점에 대한 자세한 내용은 Microsoft 기술 자료에서 다음 단어를 쿼리하십시오.
   IEEE 및 부동 및 소수점 및 appnote

IEEE는 지수에 더 많은 비트를 할당하여 더 넓은 범위의 값을 표현할 수 있습니다. MBF는 가수에 더 많은 비트를 할당하여 좁은 범위 내에서 더 정밀한 값을 표현할 수 있습니다.

일반 부동 소수점 개념

이진 부동 소수점은 부동 소수점 값의 유한한 수만 정확한 형식으로 표현할 수 있다는 것을 아는 것이 중요합니다. 기타 모든 값은 표현 가능한 가장 가까운 값이 되어야 합니다. IEEE 표준은 값을 "가장 가까운" 표현 가능한 값으로 반올림하는 방법을 지정합니다. MS-DOS용 QuickBasic은 IEEE 규칙에 따라 표준과 반올림을 지원합니다.

또한 IEEE에서 표현할 수 있는 숫자는 그 범위가 매우 넓다는 것을 염두에 두십시오. 숫자 라인에서 이들을 상상할 수 있습니다. 1.0과 -1.0 근처에는 표현 가능한 숫자가 많고 0이나 무한으로 갈수록 적어집니다.

공학 계산을 위해 디자인된 IEEE 표준의 목적은 정밀도를 최대화하여 가능한 실수와 근접한 값을 얻는 것입니다. 정밀도는 표현할 수 있는 자릿수를 나타냅니다. IEEE 표준은 허용 가능한 한도 내에 정확도와 정밀도를 모두 유지하도록 숫자의 소수부에 사용된 비트 수와 가수 전용의 비트 수의 균형을 맞추려고 시도합니다.

IEEE 세부 사항

부동 소수점 숫자는 다음 형식으로 표현됩니다. [exponent]는 이진 지수입니다.
   X =  Fraction * 2^(exponent - bias)

[Fraction]은 지수는 선행 비트가 항상 1이 되도록 조정하기 때문에 숫자의 정규화된 소수부입니다. 따라서 저장할 필요가 없어 정밀도가 한 비트 늘어납니다. 그 이유는 암시적 비트가 있기 때문입니다. 이것은 지수가 소수점 왼쪽에 한 자리가 있도록 계산하는 공학용 표기법으로 생각할 수 있습니다. 이진수를 제외하고는 1과 0만 있기 때문에 항상 첫번째 비트가 1이 되도록 지수를 처리할 수 있습니다.

[bias]는 음의 지수를 저장하지 못하도록 하는 데 사용되는 바이어스 값입니다.

단정밀도 숫자에 대한 바이어스는 127이고 배정밀도 숫자의 경우는 1023(십진수)입니다.

모두 0 및 모두 1(이진수)과 동일한 값은 특수한 경우를 표현하기 위해 예약되어 있습니다. 다양한 오류 조건을 나타내는 기타 특수한 경우가 있습니다.

단정밀도 예제

2 = 1 * 2^1 = 0100 0000 0000 0000 ... 0000 0000 = 4000 0000 hex
부호 비트는 0이며 저장된 지수는 128 또는 127에 1을 더한 이진수 100 0000 0입니다. 저장된 가수는 (1.) 000 0000 ... 0000 0000이며 암시적 선행 1과 이진 소수점이 있으며 실제 가수는 1입니다.

-2 = -1 * 2^1 = 1100 0000 0000 0000 ... 0000 0000 = C000 0000 hex
부호 비트가 설정된 것을 제외하고 +2와 같습니다. 이것은 모든 IEEE 형식 부동 소수점 숫자에 적용됩니다.

4 = 1 * 2^2 = 0100 0000 1000 0000 ... 0000 0000 = 4080 0000 hex
가수가 같고, 지수는 1씩 증가합니다. 바이어스된 값은 129 또는 이진수로 100 0000 1입니다.

6 = 1.5 * 2^2 = 0100 0000 1100 0000 ... 0000 0000 = 40C0 0000 hex
지수가 같고, 가수는 1/2정도 큽니다. (1.) 100 0000 ... 0000 0000이며 이것은 이진 소수이기 때문에 1-1/2(분수의 값은 1/2, 1/4, 1/8 등)입니다.

1 = 1 * 2^0 = 0011 1111 1000 0000 ... 0000 0000 = 3F80 0000 hex
2의 다른 제곱과 지수가 같고, 가수는 127에서 2보다 하나가 적거나 이진수로 011 1111 1입니다.

.75 = 1.5 * 2^-1 = 0011 1111 0100 0000 ... 0000 0000 = 3F40 0000 hex
바이어스된 지수는 126. 이진수로 011 1111 0이며 가수는 (1.) 100 0000 ... 0000 0000이며 1-1/2입니다.

2.5 = 1.25 * 2^1 = 0100 0000 0010 0000 ... 0000 0000 = 4020 0000 hex
1/4을 나타내는 비트가 가수에 설정된 것을 제외하고는 정확히 2와 같습니다.

0.1 = 1.6 * 2^-4 = 0011 1101 1100 1100 ... 1100 1101 = 3DCC CCCD hex
1/10은 이진 순환 소수입니다. 가수는 1.6이며 바이어스된 지수는 1.6이 16으로 나뉘어진다는 것을 나타냅니다. 이진수로 011 1101 1이며 십진수로 123입니다. 진정한 지수는 123 - 127 = -4이며 곱셈에 대한 요소는 2**-4 = 1/16임을 의미합니다. 저장된 가수는 마지막 비트에서 반올림됩니다. 이것은 표현할 수 없는 숫자를 가능한 정확하게 표현하려는 시도입니다. 1/10과 1/100을 이진수로 정확하게 표현할 수 없는 이유는 1/3이 십진수로 정확하게 표현할 수 없는 이유와 비슷합니다.

0 = 1.0 * 2^-128 = 모두 0 -- 특별한 경우.

다른 일반 부동 소수점 오류

다음은 일반 부동 소수점 오류입니다.
  1. 반올림 오류

    이 오류는 이진수의 모든 비트를 계산에 사용할 수 없을 때 발생합니다.

    예: 0.0001을 0.9900에 추가(단정밀도)

    십진수 0.0001은 다음과 같이 표현됩니다.
    (1.)10100011011011100010111 * 2^(-14+Bias)(이진수로 13개의 선행 0!)
    0.9900는 다음과 같이 표현됩니다.
    (1.)11111010111000010100011 * 2^(-1+Bias)
    이 숫자를 실제로 추가하려면 십진(이진) 소수점을 정렬해야 합니다. 이렇게 하려면 우선 비정규화되어야 합니다. 더한 결과는 다음과 같습니다.
           .000000000000011010001101 * 2^0  <- 23비트 중 11만이 유지됨
          +.111111010111000010100011 * 2^0
          ________________________________
           .111111010111011100110000 * 2^0
    
    일부 컴퓨터는 더하기를 위해 이동할 때 반올림하기 때문에 이것을 반올림 오류라고 합니다. 다른 경우는 단순히 잘라냅니다. 두 가지 매우 다른 값을 추가하거나 곱할 때마다 반올림 오류를 고려해야 합니다.
  2. 거의 같은 두 값을 빼면
           .1235
          -.1234
           _____
           .0001
    
    이 값은 정규화됩니다. 원래 숫자에서는 유효 숫자가 네 개이지만 결과에는 유효 숫자가 하나뿐입니다.
  3. 오버플로 및 언더플로

    이것은 결과가 데이터 유형으로 표현하기에 너무 크거나 너무 적을 때 발생합니다.
  4. 양자화 오류

    이것은 부동 소수점 표준에 의해 정확한 형태로 표현할 수 없는 수에서 발생합니다.
  5. 매우 작은 수로 나누기

    이것은 "0으로 나누기" 오류를 발생시키거나 다음 예처럼 잘못된 결과를 생성할 수 있습니다.
          A = 112000000
          B = 100000
          C = 0.0009
          X = A - B / C
    
    MS-DOS용 QuickBasic에서 X는 이제 정확한 값인 900000 대신 888887의 값을 갖습니다.
  6. 출력 오류

    이런 종류의 오류는 출력 함수가 작업 중인 값을 바꿀 때 발생합니다.

속성

기술 자료: 42980 - 마지막 검토: 2005년 8월 24일 수요일 - 수정: 2.2
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Visual Basic 2.0 Standard Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic for MS-DOS
  • Microsoft Visual Basic 1.0 Standard Edition
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft Cinemania 97 Standard Edition
키워드:?
KB42980
더 이상 지원되지 않는 제품의 KB 내용에 대한 고지 사항
이 문서에서는 Microsoft에서 더 이상 지원하지 않는 제품에 대해 설명합니다. 따라서 이 문서는 "있는 그대로" 제공되며 업데이트되지 않습니다.

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com