programing

부동소수점비교

prostudy 2022. 5. 20. 21:34
반응형

부동소수점비교

int main()
{
    float a = 0.7;
    float b = 0.5;
    if (a < 0.7)
    {
       if (b < 0.5) printf("2 are right");
       else         printf("1 is right");
    }
    else printf("0 are right");
}

나는 이 코드의 출력이0 are right그러나 실망스럽게도 그 결과물은1 is right왜?

int main()
{
    float a = 0.7, b = 0.5; // These are FLOATS
    if(a < .7)              // This is a DOUBLE
    {
      if(b < .5)            // This is a DOUBLE
        printf("2 are right");
      else
        printf("1 is right");
    }
    else
      printf("0 are right");
}

플로트는 비교하는 동안 2배로 승격되며, 플로트는 2배보다 정밀도가 낮기 때문에 플로트는 0.7이 2배와 같지 않다.이 경우 플로트 0.7은 승진할 때 2배로 0.7보다 떨어진다.그리고 크리스찬이 말했듯이 0.5는 항상 2의 힘을 정확하게 나타내므로 시험은 예상대로 작동한다.0.5 < 0.5거짓이다.

다음 중 하나를 선택하십시오.

  • 변화하다floatdouble또는:
  • 변화하다.7그리고.5.7f그리고.5f,

그러면 당신은 예상되는 행동을 하게 될 것이다.

문제는 비교 대상 상수가double아닌float.또한, 상수를 의 인자와 같이 쉽게 표현할 수 있는 것으로 바꾸는 것.5라고 말할 것이다0 is right예를 들어,

main()
{
    float a=0.25,b=0.5; 
    if(a<.25) 
       {
       if(b<.5) 
               printf("2 are right");
       else
               printf("1 is right");
       }
else
printf("0 are right");
}

출력:

0 are right

플로트와 이중 비교위한 가장 효과적인 방법에 대한 이 SO 질문이 이 주제를 다룬다.

또한, 부동 소수점 비교에 대한 cygnus의 이 기사는 우리에게 다음과 같은 몇 가지 팁을 준다.

IEEE 플로트와 이중 형식은 "사전순으로 정렬"되도록 설계되었으며, IEEE 설계자 William Kahan은 "같은 형식의 부동 소수점 두 개(예: x < y )를 주문하면, 그 비트를 리퀴드 정수로 재해석할 때 동일한 방식으로 정렬한다"를 의미한다.

이것은 우리가 기억 속에 떠 있는 두 개의 물체를 가지고, 그들의 비트 패턴을 정수로 해석하고 비교한다면, 우리는 부동소수점 비교를 하지 않고도, 어느 것이 더 큰지 알 수 있다는 것을 의미한다.C/C++ 언어에서 이 비교는 다음과 같다.

if (*(int*)&f1 < *(int*)&f2)

이 매력적인 구문은 f1의 주소를 취해서 정수 포인터로 취급하고 이를 무시하는 것을 의미한다.이 모든 포인터 작업은 비싸 보이지만 기본적으로 모두 취소되고 'f1을 정수로 처리'를 의미한다.f2에도 같은 구문을 적용하기 때문에 전체 선은 '플랫폼 대신 정수로 해석된 인메모리 표현을 사용하여 f1과 f2를 비교한다'는 뜻이다.

플로트에서 더블로 전환하면서 반올림 문제가 발생했기 때문이다.

일반적으로 부유물과 평등을 비교하는 것은 위험한 사업이다( >의 경계에서 바로 비교하는 것처럼 사실상 당신이 하고 있는 일이다), 소수점에서는 (1/3과 같은) 특정 분수를 정확하게 표현할 수 없다는 것을 기억하라, 2진수에서도 같은 말을 할 수 있다.

0.5= 0.1는 플로트 또는 더블로 동일할 것이다.

0.7=0.10110011001100은 영원히 수 없으며 오류가 간에 수 있다.7은 2진수로 정확하게 나타낼 수 없으며 라운딩 오류가 발생하고 플로트와 더블이 매우 약간 다를 수 있다.

부동 소수점과 이중 소수점 사이를 이동하면 소수점 수가 서로 다르므로 불일치가 발생한다는 점에 유의하십시오.

또한 0의 논리에 오류가 있다.출력 0이 맞으면 b를 체크하지 않는다.하지만 당신이 정말로 성취하려고 하는 것이 무엇인지에 있어서 그 모든 것은 약간 신비롭다.부유물과 복식 간의 부동소수점 비교는 분 단위로 변동하므로 상황에 맞는 델타 '허용' 변동과 비교해야 한다.나는 항상 일을 수행하기만 하는 인라인 함수를 통해 이 일을 해 왔다(매크로로 한번 해보긴 했는데 너무 지저분하다).어쨌든, 그래, 라운딩 문제는 이런 종류의 예와 함께 많다.부동소수점 내용을 읽고, .7이 .7f와 다르다는 것을 알고, .7을 플로트에 할당하면 두 배가 뜬다는 것을 알게 되고, 따라서 값의 정확한 성격을 바꾸게 된다.그러나 당신이 나에게 보낸 b의 blared를 확인했을 때부터 b가 틀렸다는 프로그래밍 가정은, 나는 그 점을 주목해야 했다.

참조URL: https://stackoverflow.com/questions/7011184/floating-point-comparison

반응형