programing

문자열을 더블로 변환하면 리터럴 더블과 같습니까?

codeshow 2023. 10. 9. 23:41
반응형

문자열을 더블로 변환하면 리터럴 더블과 같습니까?

예를 들어,

assert(atof("1.2") == 1.2);

어떤 플로트를 사용하든 상관없이?

부동 소수점 정밀도가 정확하지 않은 것으로 알고 있는데, 정확하지 않은데 반올림에서 이진으로 가는 것도 같은 두 배가 나오는 건가요?

이것은 C 표준에서는 보장되지 않습니다.소스 코드에서 부동 소수점 리터럴을 변환하는 시맨틱스는 C 2011 [draft N1570] 6.4.4.2에 명시되어 있습니다.이것은 권장하지만 필수는 아니지만 부동 소수점 상수의 변환 시간 변환은 라이브러리 함수에 의한 문자열의 실행 시간 변환과 일치해야 한다는 것을 말합니다.strtod.

그 이상으로, 표준은 심지어 다음과 같은 수학적 가치를 가진 두 개의 다른 리터럴을 요구하지 않습니다.1.23그리고.1.230, 같은 값으로 바꾸다이러한 예는 동일한 소스 형태의 부동 소수점 상수가 동일한 값으로 변환되어야 한다는 문단의 각주인 표준의 각주 75에서 비롯됩니다.따라서,1.23소스에 나타나는 모든 값이 항상 동일하게 변환됩니다.1.230반드시 다음과 같은 값으로 변환되지는 않습니다.1.23아니면123e-2.심지어.123e-2그리고.123e-02다를 수도 있습니다.

atof(p)7.22.1.2에 다음과 동등하도록 명시되어 있습니다.strtod(p, (char **) NULL)그들이 실수로 행동하는 것을 제외하고는 말입니다.strtod7.22.1.3에 명시되어 있습니다.이 조항은 정확성을 위해 권장되는 몇 가지 방법이 있지만 리터럴의 번역-시간 변환에 대해서는 침묵하고 있습니다.

이 검사는 구현에 의존적일 수밖에 없기 때문에 다음과 같은 간단한 테스트 스크립트를 작성했습니다.

#include <stdio.h>
#include <stdlib.h>

int main()
  {
  double d1 = 1.2;
  double d2 = atof("1.2");
  char *p;
  double d3 = strtod("1.2", &p);

  printf("d1 = %40.40f\n", d1);
  printf("d2 = %40.40f\n", d2);
  printf("d3 = %40.40f\n", d3);

  if(d1 != d2)
    printf("d1 != d2\n");

  if(d2 != d3)
    printf("d2 != d3\n");
  }

HPC/C++ 컴파일러 버전 A.06.25.02의 경우 다음과 같이 출력됩니다.

d1 = 1.1999999999999999555910790149937383800000
d2 = 1.1999999999999999555910790149937383800000
d3 = 1.1999999999999999555910790149937383800000

이것은 컴파일러에 의해 수행되는 (적어도 1.2의) 변환이 수행되는 변환과 일치함을 보여줍니다.atof그리고.strtod.

군사 공학에서는 항상 실제 유동 비교 값 주위에 허용 오차 대역을 +/- 0.000001로 배치하여 이 문제를 설명합니다.이렇게 하면 당신이 진정으로 비교하고 있는 것이 무엇인지 알 수 있고 알고리즘이 무엇을 하도록 설계되었는지 오염을 방지하는 데 도움이 됩니다.부동 소수점 번호를 사용할 때는 항상 퍼지 숫자를 사용하여 작업합니다. 이 경우에는 비교가 어렵거나 하지 않아야 합니다.

언급URL : https://stackoverflow.com/questions/49614752/will-converting-a-string-to-a-double-equal-the-literal-double

반응형