[math] 부동 소수점 수학이 깨졌습니까?

다음 코드를 고려하십시오.

0.1 + 0.2 == 0.3  ->  false
0.1 + 0.2         ->  0.30000000000000004

왜 이러한 부정확성이 발생합니까?



답변

이진 부동 소수점 수학은 다음과 같습니다. 대부분의 프로그래밍 언어에서는 IEEE 754 표준을 기반으로합니다 . 문제의 요점은 숫자가이 형식으로 정수에 2의 거듭 제곱으로 표시된다는 것입니다. 유리수 (예를 들면 0.1, 이는 1/10그 분모가 2의 제곱이 정확하게 표현 될 수 없다).

들어 0.1표준의 binary64형식, 표현이 정확하게과 같이 쓸 수있다

  • 0.1000000000000000055511151231257827021181583404541015625 십진수 또는
  • 0x1.999999999999ap-4에서 C99의 hexfloat 표기 .

대조적으로, 유리수 0.1는 즉 1/10,

  • 0.1 십진수 또는
  • 0x1.99999999999999...p-4C99 hexfloat 표기법과 유사하며, 여기서 ...9는 끝없는 시퀀스를 나타냅니다.

상수 0.20.3프로그램 의 상수도 실제 값과 비슷합니다. 가장 가까운 것을 일 double에이 0.2유리수보다 큰 0.2하지만 가장 가까운 것을 double에이 0.3합리적인 수보다 작다 0.3. 합 0.1과 합은 0.2합리적 수보다 커서 0.3코드의 상수에 동의하지 않습니다.

부동 소수점 산술 문제의 상당히 포괄적 인 처리는 모든 컴퓨터 과학자 가 부동 소수점 산술에 대해 알아야 할 것 입니다. 보다 이해하기 쉬운 설명은 floating-point-gui.de를 참조하십시오 .

참고 : 모든 위치 (base-N) 숫자 시스템은이 문제를 정밀하게 공유합니다.

평범한 오래된 십진수 (기본 10) 숫자는 같은 문제가 있으므로 1/3과 같은 숫자는 0.333333333으로 끝나는 것입니다 …

십진법으로 표현하기 쉽지만 이진법에 맞지 않는 숫자 (3/10)를 우연히 발견했습니다. 1/16은 십진수 (0.0625)의 못생긴 숫자이지만, 이진수에서는 10,000의 십진수 (0.0001)만큼 깔끔한 것처럼 보입니다. **- 우리의 일상 생활에서 기본 2 수 체계를 사용하는 습관, 당신은 심지어 그 숫자를보고 뭔가를 반으로, 반으로 반복하여 도착할 수 있다는 것을 본능적으로 이해합니다.

** 물론 부동 소수점 숫자가 메모리에 저장되는 방식이 아닙니다 (과학 표기법의 형태를 사용함). 그러나 이진 부동 소수점 정밀도 오류는 일반적으로 우리가 작업하고자하는 “실제 세계”숫자가 10의 거듭 제곱이기 때문에 발생하는 경향을 보여줍니다. 오늘. 그렇기 때문에 우리는 “7/5마다 5″대신 71 %와 같은 것을 말할 것입니다. (71 %는 근사치입니다.

따라서 아니오 : 이진 부동 소수점 숫자는 손상되지 않으며 다른 모든 base-n 숫자 시스템만큼 불완전합니다. 🙂

측면 참고 : 프로그래밍에서 플로트 작업

실제로이 정밀도 문제는 부동 소수점 숫자를 표시하기 전에 원하는 소수 자릿수로 반올림하기 위해 반올림 함수를 사용해야 함을 의미합니다.

또한 동등성 테스트를 약간의 공차를 허용하는 비교로 대체해야합니다. 이는 다음을 의미합니다.

마십시오 하지if (x == y) { ... }

대신 if (abs(x - y) < myToleranceValue) { ... }.

abs절대 값은 어디에 있습니까 ? myToleranceValue특정 응용 프로그램에 대해 선택해야합니다. 허용 할 “흔들기 방”의 양과 비교할 가장 큰 숫자 (정밀성 문제로 인해)와 관련이 있습니다. ). 선택한 언어에서 “엡실론”스타일 상수를주의하십시오. 이들은 공차 값으로 사용 되지 않습니다 .


답변

하드웨어 디자이너의 관점

부동 소수점 하드웨어를 디자인하고 빌드하기 때문에 하드웨어 디자이너의 관점을 추가해야한다고 생각합니다. 오류의 원인을 아는 것은 소프트웨어에서 일어나는 일을 이해하는 데 도움이 될 수 있으며 궁극적으로 이것이 부동 소수점 오류가 발생하고 시간이 지남에 따라 축적되는 이유를 설명하는 데 도움이되기를 바랍니다.

1. 개요

엔지니어링 관점에서 볼 때 대부분의 부동 소수점 연산에는 부동 소수점 계산을 수행하는 하드웨어에 마지막 한 단위의 절반 미만의 오류 만 있으면되므로 일부 오류 요소가 있습니다. 따라서 대부분의 하드웨어는 부동 소수점 분할에서 특히 문제가되는 단일 작업 에 대해 마지막 위치에서 한 단위의 절반 미만의 오류를 생성하는 데 필요한 정밀도로 중지됩니다 . 단일 연산을 구성하는 것은 장치가 수행하는 피연산자 수에 따라 다릅니다. 대부분 2 개이지만 일부 단위에는 3 개 이상의 피연산자가 필요합니다. 이 때문에 시간이 지남에 따라 오류가 더해 지므로 반복 된 작업으로 인해 원하는 오류가 발생한다고 보장 할 수 없습니다.

2. 표준

대부분의 프로세서는 IEEE-754 표준을 따르지만 일부는 비정규 화 된 표준 또는 다른 표준을 사용합니다. 예를 들어 IEEE-754에는 비정규 화 된 모드가있어 정밀도를 희생시키면서 매우 작은 부동 소수점 숫자를 표현할 수 있습니다. 그러나 다음은 일반적인 작동 모드 인 IEEE-754의 정규화 된 모드를 다룹니다.

IEEE-754 표준에서, 하드웨어 설계자들은 마지막 장소에서 한 단위의 절반보다 작은 오류 / 엡실론의 값을 허용하며 결과는 마지막 한 단위의 절반보다 작아야합니다. 하나의 작업 장소. 이것은 반복되는 작업이있을 때 오류가 더해지는 이유를 설명합니다. IEEE-754 배정도의 경우 53 비트는 부동 소수점 숫자 (예 : 5.3e5의 5.3)의 가수 (mantissa)라고하는 숫자 부분 (정규화 된)을 나타내는 데 사용되므로 54 번째 비트입니다. 다음 섹션에서는 다양한 부동 소수점 연산에서 하드웨어 오류의 원인에 대해 자세히 설명합니다.

3. 나눗셈에서 반올림 오류의 원인

부동 소수점 나누기 오류의 주요 원인은 몫을 계산하는 데 사용되는 나누기 알고리즘입니다. 대부분의 컴퓨터 시스템은 주로 Z=X/Y,Z = X * (1/Y). 나누기는 반복적으로 계산됩니다. 즉, 각 사이클은 원하는 정밀도에 도달 할 때까지 몫의 일부 비트를 계산합니다. IEEE-754의 경우 마지막 위치에서 1 단위 미만의 오류가있는 항목입니다. Y (1 / Y)의 역수 표는 느린 나눗셈에서 몫 선택 표 (QST)라고하며 몫 선택 표의 비트 단위 크기는 일반적으로 기수의 폭 또는 비트 수입니다. 각 반복에서 계산 된 몫과 가드 비트. IEEE-754 표준의 배정도 (64 비트)의 경우 디바이더의 기수 크기에 몇 가드 비트 k를 더한 값 k>=2입니다. 예를 들어, 한 번에 몫의 2 비트 (기수 4)를 계산하는 디바이더에 대한 일반적인 몫 선택 표는 2+2= 4비트 (플러스 옵션 비트)가됩니다.

3.1 구간 반올림 오차 : 역수 근사

몫 선택 테이블에있는 왕복 수는 나누기 방법 에 따라 다릅니다. SRT 나누기와 같은 느린 나누기 또는 Goldschmidt 나누기와 같은 빠른 나누기; 각 항목은 가능한 가장 낮은 오류를 생성하기 위해 나누기 알고리즘에 따라 수정됩니다. 어쨌든 모든 역수는 근사치입니다.실제의 역수와 오류 요소를 소개합니다. 느린 나눗셈과 빠른 나눗셈 방법은 몫을 반복적으로 계산합니다. 즉, 몫의 일부 비트가 각 단계에서 계산 된 다음 결과가 피제수에서 빼고 디바이더가 오차가 1의 절반보다 작을 때까지 단계를 반복합니다. 마지막 장소에서 단위. 느린 나눗셈 방법은 각 단계에서 몫의 고정 자릿수를 계산하며 일반적으로 구축 비용이 저렴하고 빠른 나눗셈 방법은 단계 당 가변 자릿수를 계산하며 일반적으로 구축 비용이 더 비쌉니다. 나누기 방법의 가장 중요한 부분은 대부분이 역수 의 근사 로 반복 곱셈에 의존 하므로 오류가 발생하기 쉽다는 것입니다.

4. 다른 작업에서 반올림 오류 : 잘림

모든 작업에서 반올림 오류의 또 다른 원인은 IEEE-754가 허용하는 최종 응답의 다른 절단 모드입니다. 잘림, 0으로 반올림 , 가장 가까운 반올림 (기본값), 반올림 및 반올림이 있습니다. 모든 방법은 단일 작업을 위해 마지막에 한 단위 미만의 오차 요소를 도입합니다. 시간이 지남에 따라 작업을 반복하면 잘림도 결과 오류에 누적됩니다. 이 잘림 오류는 지수에 특히 문제가 있으며, 여기에는 어떤 형태의 반복 곱셈이 포함됩니다.

5. 반복 작업

부동 소수점 계산을 수행하는 하드웨어는 단일 작업의 마지막 위치에서 한 단위의 절반 미만의 오류로 결과를 생성하기 만하면되기 때문에 오류를 보지 않으면 반복 된 작업보다 오류가 커집니다. 이는 경계 오류가 필요한 계산에서 수학자 들이 IEEE-754 의 마지막 위치에서 가장 가까운 자리에서 짝수 자릿수를 사용하는 등의 방법을 사용하는 이유입니다. 아웃 및 간격 산술 의 변화와 함께 IEEE 754 라운딩 모드반올림 오류를 예측하고 수정합니다. IEEE-754의 기본 반올림 모드는 다른 반올림 모드에 비해 상대적 오류가 낮기 때문에 가장 가까운 짝수로 반올림합니다 (마지막).

기본 반올림 모드 인 마지막 자리에서 가장 가까운 자리수까지도 한 번의 작업으로 마지막 자리에서 한 단위의 절반 미만의 오류를 보장합니다. 잘림, 반올림 및 반올림 만 사용하면 마지막 위치에서 한 단위의 절반보다 크지 만 마지막 위치에서 하나보다 적은 오류가 발생할 수 있으므로 이러한 모드는 그렇지 않은 경우 권장되지 않습니다. 간격 산술에 사용됩니다.

6. 요약

요컨대, 부동 소수점 연산에서 오류가 발생하는 근본적인 이유는 하드웨어에서 잘림과 나눗셈에서 역수가 잘림의 조합입니다. IEEE-754 표준은 단일 작업의 마지막 위치에서 한 단위의 절반 미만의 오류 만 필요하므로, 반복 작업에 대한 부동 소수점 오류는 수정하지 않으면 더해집니다.


답변

.1 또는 1/10을 기수 2 (이진)로 변환하면 기수 10에서 1/3을 나타내려고하는 것처럼 소수점 다음에 반복되는 패턴이 나타납니다. 일반 부동 소수점 방법을 사용하여 정확한 수학.


답변

여기에있는 대부분의 답변은이 질문을 매우 건조하고 기술적 인 용어로 해결합니다. 정상적인 인간이 이해할 수있는 용어로이 문제를 해결하고 싶습니다.

피자를 자르려고한다고 상상해보십시오. 피자 조각을 정확하게 자를 수있는 로봇 피자 커터가 있습니다 반으로 . 피자 전체를 반으로 줄이거 나 기존 슬라이스를 반으로 줄 수 있지만, 어쨌든 반은 항상 정확합니다.

그 피자 커터는 매우 미세한 움직임을 가지고 있으며, 당신이 전체 피자로 시작하는 경우, 그 반감, 그리고 작은 조각 각 시간을 절반으로 계속, 당신은 반감을 할 수있는 53 번 슬라이스도 높은 정밀도의 능력에 대해 너무 작하기 전에 . 이 시점에서 더 이상 해당 슬라이스를 절반으로 줄일 수 없지만 그대로 포함하거나 제외해야합니다.

이제 피자의 1/10 (0.1) 또는 1/5 (0.2)를 추가하는 방식으로 모든 슬라이스를 어떻게 조각 하시겠습니까? 실제로 그것에 대해 생각하고 해결해보십시오. 신화적인 정밀 피자 커터가 있다면 실제 피자를 사용해보십시오. 🙂


물론 대부분의 숙련 된 프로그래머는 실제 답을 알고 있습니다. 즉, 슬라이스를 사용하여 피자를 정확히 10 분의 5 또는 5 분의 1로 분할 할 수있는 방법이 없다는 것입니다. 당신은 꽤 좋은 근사를 할 수 있고, 대략 0.2의 근사치 0.1을 더하면 대략 0.3의 근사치를 얻지 만 여전히 근사치입니다.

배정 밀도 숫자 (피자 53 배를 절반으로 줄일 수있는 정밀도)의 경우 0.1보다 작거나 큰 숫자는 0.099999999999999991671672731131132594682276248931884765625 및 0.1000000000000000055511151231257827021181583404541015625입니다. 후자는 전자보다 0.1에 훨씬 더 가깝기 때문에 0.1의 입력이 주어지면 숫자 파서는 후자를 선호합니다.

(두 숫자의 차이는 “가장 작은 슬라이스”입니다. 여기에는 상향 바이어스를 도입하거나 제외를 포함하여 하향 바이어스를 도입하기로 결정해야합니다. 해당 최소 슬라이스에 대한 기술적 용어는 ulp 입니다.)

0.2의 경우 숫자는 모두 동일하며 2 배로 확장되었습니다. 다시, 0.2보다 약간 큰 값을 선호합니다.

두 경우 모두 0.1과 0.2의 근사치에는 약간의 상향 바이어스가 있습니다. 이러한 바이어스를 충분히 추가하면 원하는 수에서 멀어지고 멀어지게됩니다. 실제로 0.1 + 0.2의 경우 바이어스는 결과 숫자가 더 이상 가장 가까운 숫자가 아닐 정도로 충분히 높습니다. ~ 0.3.

특히 0.1 + 0.2는 실제로 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125 인 반면, 0.3에 가장 가까운 숫자는 실제로 0.299999999999999988897769753748434595763683319091796875입니다.


PS 일부 프로그래밍 언어는 슬라이스를 정확히 10 분할로 분할 할 수있는 피자 절단기를 제공합니다 . 그러한 피자 절단기는 흔하지 않지만, 하나에 접근 할 수 있다면 정확히 10 분의 1 또는 5 분의 1의 슬라이스를 얻을 수있을 때 사용해야합니다.

(원래 Quora에 게시되었습니다.)


답변

부동 소수점 반올림 오류. 소수점 이하 자릿수 5가 누락되어 10을 밑으로하는 것처럼 0.1을 밑이 2로 정확하게 표현할 수 없습니다. 1/3은 소수를 나타 내기 위해 무한한 자릿수를 취하지 만 밑이 3이면 “0.1”입니다. 0.1은 10 진수가 아닌 2 진수의 무한 자릿수를 사용합니다. 그리고 컴퓨터에는 무한한 양의 메모리가 없습니다.


답변

다른 정답 외에도 부동 소수점 산술 문제를 피하기 위해 값의 스케일링을 고려할 수 있습니다.

예를 들면 다음과 같습니다.

var result = 1.0 + 2.0;     // result === 3.0 returns true

… 대신에:

var result = 0.1 + 0.2;     // result === 0.3 returns false

표현식 0.1 + 0.2 === 0.3falseJavaScript로 반환 되지만 다행스럽게도 부동 소수점의 정수 산술은 정확하므로 소수 자릿수 표시 오류를 스케일링으로 피할 수 있습니다.

실제적인 예로, 정확도가 가장 중요한 부동 소수점 문제를 피하려면 1 을 센트 수를 나타내는 정수 ( 달러 2550대신 센트)로 처리 하는 것이 좋습니다 25.50.


1 Douglas Crockford : JavaScript : 좋은 부분 : 부록 A-끔찍한 부분 (105 페이지) .


답변

내 대답은 꽤 길기 때문에 세 부분으로 나눕니다. 문제는 부동 소수점 수학에 관한 것이므로 기계가 실제로하는 일에 중점을 둡니다. 또한 두 배 (64 비트) 정밀도로 특정화했지만 인수는 모든 부동 소수점 산술에 동일하게 적용됩니다.

전문

IEEE 754 배정도 이진 부동 소수점 포맷 (binary64)는 숫자 형식의 수를 나타낸다

값 = (-1) ^ s * (1.m 51 m 50 … m 2 m 1 m 0 ) 2 * 2 e-1023

64 비트로 :

  • 첫 번째 비트는 부호 비트입니다 . 1숫자가 음수이면 0그렇지 않으면 1 입니다.
  • 다음 11 비트는 지수 이며 1023 으로 오프셋 됩니다. 즉, 배정 밀도 숫자에서 지수 비트를 읽은 후 2의 거듭 제곱을 얻으려면 1023을 빼야합니다.
  • 나머지 52 비트는 유효 (또는 가수)입니다. 가수에서 ‘임시적’ 1.2 진수 값의 최상위 비트 가이므로 항상 2를 생략합니다 1.

1 – IEEE 754는의 개념을 허용 제로 서명+0-0다르게 취급된다 : 1 / (+0)무한대입니다; 1 / (-0)음의 무한대입니다. 0 값의 경우 가수 및 지수 비트는 모두 0입니다. 참고 : 0 값 (+0 및 -0)은 명시 적으로 비정규 2 로 분류되지 않습니다 .

2- 오프셋 지수가 0이고 암시적인 비정규 숫자 의 경우에는 해당되지 않습니다 0.. 비정규 배정 밀도 숫자의 범위는 d min ≤ | x | ≤ d max , 여기서 d min (가장 작은 숫자가 아닌 가장 작은 숫자)는 2-1023-51 (≈ 4.94 * 10-324 )이고 d max (가장 큰 수가 비정규 수이며 가수가 전체적으로 1s로 구성됨 )는 2-1023입니다 + 1 – 2 -1023 – 51 (* 10 ≈ 2.225 -308 ).


배정도 숫자를 이진수로 바꾸기

배정도 부동 소수점 숫자를 이진수로 변환하는 많은 온라인 변환기가 존재 하지만 (예 : binaryconvert.com ) 배정도 숫자에 대한 IEEE 754 표현을 얻기위한 샘플 C # 코드가 있습니다 (세 부분을 콜론 ( :) 으로 구분 ) :

public static string BinaryRepresentation(double value)
{
    long valueInLongType = BitConverter.DoubleToInt64Bits(value);
    string bits = Convert.ToString(valueInLongType, 2);
    string leadingZeros = new string('0', 64 - bits.Length);
    string binaryRepresentation = leadingZeros + bits;

    string sign = binaryRepresentation[0].ToString();
    string exponent = binaryRepresentation.Substring(1, 11);
    string mantissa = binaryRepresentation.Substring(12);

    return string.Format("{0}:{1}:{2}", sign, exponent, mantissa);
}

요점 파악 : 원래 질문

(TL; DR 버전의 하단으로 건너 뛰기)

Cato Johnston (질문자)은 왜 0.1 + 0.2! = 0.3인지 물었습니다.

이진수로 작성 (콜론으로 세 부분을 분리)하면 IEEE 754 값은 다음과 같습니다.

0.1 => 0:01111111011:1001100110011001100110011001100110011001100110011010
0.2 => 0:01111111100:1001100110011001100110011001100110011001100110011010

가수는의 반복 자릿수로 구성 0011됩니다. 이것은 계산에 오류가있는 이유의 핵심입니다 -0.1, 0.2 및 0.3은 1 / 9, 1/3 또는 1/7을 초과 하는 유한 수의 이진 비트로 정확하게 이진수로 표현 될 수 없습니다 . 십진수 .

또한 지수의 거듭 제곱을 52만큼 줄이고 이진 표현의 점을 52 자리만큼 오른쪽으로 옮길 수 있습니다 ( 10-3 * 1.23 == 10-5 * 123 과 유사 ). 그러면 이진 표현을 a * 2 p 형식으로 나타내는 정확한 값으로 표현할 수 있습니다. 여기서 ‘a’는 정수입니다.

지수를 10 진수로 변환하고 오프셋을 제거하고 암시 적 1(대괄호로 표시)을 다시 추가하면 0.1과 0.2는 다음과 같습니다.

0.1 => 2^-4 * [1].1001100110011001100110011001100110011001100110011010
0.2 => 2^-3 * [1].1001100110011001100110011001100110011001100110011010
or
0.1 => 2^-56 * 7205759403792794 = 0.1000000000000000055511151231257827021181583404541015625
0.2 => 2^-55 * 7205759403792794 = 0.200000000000000011102230246251565404236316680908203125

두 개의 숫자를 더하려면 지수는 동일해야합니다.

0.1 => 2^-3 *  0.1100110011001100110011001100110011001100110011001101(0)
0.2 => 2^-3 *  1.1001100110011001100110011001100110011001100110011010
sum =  2^-3 * 10.0110011001100110011001100110011001100110011001100111
or
0.1 => 2^-55 * 3602879701896397  = 0.1000000000000000055511151231257827021181583404541015625
0.2 => 2^-55 * 7205759403792794  = 0.200000000000000011102230246251565404236316680908203125
sum =  2^-55 * 10808639105689191 = 0.3000000000000000166533453693773481063544750213623046875

합이 2 n * 1. {bbb} 형식이 아니므로 지수를 1 씩 증가시키고 소수 ( binary ) 점을 이동하여 다음을 얻습니다.

sum = 2^-2  * 1.0011001100110011001100110011001100110011001100110011(1)
    = 2^-54 * 5404319552844595.5 = 0.3000000000000000166533453693773481063544750213623046875

가수에 53 비트가 있습니다 (53 번째는 위의 꺾쇠 괄호 안에 있음). IEEE 754 의 기본 반올림 모드 는 ‘ 가장 반올림 ‘입니다. 즉, 숫자 x 가 두 값 ab 사이에 있으면 최하위 비트가 0 인 값이 선택됩니다.

a = 2^-54 * 5404319552844595 = 0.299999999999999988897769753748434595763683319091796875
  = 2^-2  * 1.0011001100110011001100110011001100110011001100110011

x = 2^-2  * 1.0011001100110011001100110011001100110011001100110011(1)

b = 2^-2  * 1.0011001100110011001100110011001100110011001100110100
  = 2^-54 * 5404319552844596 = 0.3000000000000000444089209850062616169452667236328125

참고 와 B가 마지막 비트 다르다; + = . 이 경우 최하위 비트가 0 인 값은 b 이므로 합은 다음과 같습니다....00111...0100

sum = 2^-2  * 1.0011001100110011001100110011001100110011001100110100
    = 2^-54 * 5404319552844596 = 0.3000000000000000444089209850062616169452667236328125

0.3의 이진 표현은 다음과 같습니다.

0.3 => 2^-2  * 1.0011001100110011001100110011001100110011001100110011
    =  2^-54 * 5404319552844595 = 0.299999999999999988897769753748434595763683319091796875

이는 0.1과 0.2의 합을 2-54 의 이진수 표현과 만 다릅니다 .

0.1과 0.2의 이진 표현은 IEEE 754가 허용하는 숫자를 가장 정확하게 표현한 것입니다. 기본 반올림 모드로 인해 이러한 표현을 추가하면 최하위 비트에서만 다른 값이 생성됩니다.

TL; DR

0.1 + 0.2IEEE 754 이진 표현으로 작성 하고 (세 부분을 구분하는 콜론으로) 이것을 (와 비교하면) 0.3구별 된 비트를 대괄호로 묶었습니다.

0.1 + 0.2 => 0:01111111101:0011001100110011001100110011001100110011001100110[100]
0.3       => 0:01111111101:0011001100110011001100110011001100110011001100110[011]

십진수로 다시 변환하면이 값은 다음과 같습니다.

0.1 + 0.2 => 0.300000000000000044408920985006...
0.3       => 0.299999999999999988897769753748...

차이는 정확히 2 -54 5.5511151231258 × 10 ~ 인 -17 원래 값에 비해 미미한는 (많은 애플리케이션) -.

부동 소수점 숫자의 마지막 몇 비트를 비교하는 것은 본질적으로 ” 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 것 “(이 답변의 모든 주요 부분을 다루고 있음) 을 읽는 사람이 알듯이 본질적으로 위험 합니다.

대부분의 계산기는 이 문제를 해결하기 위해 추가 가드 숫자 를 사용합니다. 이 방법 0.1 + 0.20.3마지막 몇 비트가 반올림됩니다.