수색…


부동 소수점 숫자는 이상합니다.

거의 모든 단일 프로그래머가 만드는 첫 번째 실수는이 코드가 의도 한대로 작동한다고 가정하는 것입니다.

float total = 0;
for(float a = 0; a != 2; a += 0.01f) {
    total += a;
}

초보 프로그래머는 0, 0.01, 0.02, 0.03, ..., 1.97, 1.98, 1.99 범위의 모든 단일 숫자를 합산하여 수학적으로 정답 인 결과 199 를 산출한다고 가정합니다.

이 사실을 알 수없는 두 가지 일이 발생합니다.

  1. 서면으로 작성된 프로그램은 결론을 내리지 않습니다. a2 와 결코 같지 않으며 루프는 종료되지 않습니다.
  2. 루프 논리를 다시 작성하여 a < 2 를 확인하면 루프가 종료되지만 총계가 199 와 다른 결과가됩니다. IEEE754를 준수하는 시스템에서는 대개 약 201 까지 합쳐집니다.

부동 소수점 숫자는 할당 된 값의 근사값을 나타냅니다 .

고전적인 예는 다음과 같습니다.

double a = 0.1;
double b = 0.2;
double c = 0.3;
if(a + b == c)
    //This never prints on IEEE754-compliant machines
    std::cout << "This Computer is Magic!" << std::endl; 
else
    std::cout << "This Computer is pretty normal, all things considered." << std::endl;

우리 프로그래머가 보는 것은 base10에 쓰여있는 세 개의 숫자이지만, 컴파일러 (및 기본 하드웨어)가 볼 수있는 것은 이진수입니다. 0.1 , 0.20.310 완전히 나눗셈을해야하기 때문에 (기본 10 시스템에서는 매우 쉽지만 기본 2 시스템에서는 불가능 함)이 숫자는 숫자 1/3 은 base-10의 부정확 한 형식 0.333333333333333... 에 저장되어야합니다.

//64-bit floats have 53 digits of precision, including the whole-number-part.
double a =     0011111110111001100110011001100110011001100110011001100110011010; //imperfect representation of 0.1
double b =     0011111111001001100110011001100110011001100110011001100110011010; //imperfect representation of 0.2
double c =     0011111111010011001100110011001100110011001100110011001100110011; //imperfect representation of 0.3
double a + b = 0011111111010011001100110011001100110011001100110011001100110100; //Note that this is not quite equal to the "canonical" 0.3!


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow