Programing

C에서 double이 C ++보다 소수를 더 적게 인쇄하는 이유는 무엇입니까?

lottogame 2020. 11. 25. 07:27
반응형

C에서 double이 C ++보다 소수를 더 적게 인쇄하는 이유는 무엇입니까?


나는 0.1을 double로 선언 한 C에이 코드가 있습니다.

#include <stdio.h> 
int main() {
    double a = 0.1;

    printf("a is %0.56f\n", a);
    return 0;
}

이것이 인쇄되는 것입니다. a is 0.10000000000000001000000000000000000000000000000000000000

C ++의 동일한 코드,

#include <iostream>
using namespace std;
int main() {
    double a = 0.1;

    printf("a is %0.56f\n", a);
    return 0;
}

이것이 인쇄되는 것입니다. a is 0.1000000000000000055511151231257827021181583404541015625

차이점은 무엇입니까? 둘 다 읽을 때 8 바이트가 할당됩니까? C ++는 어떻게 소수 자리에 더 많은 숫자를 인쇄합니까?

또한 소수점 55 자리까지 어떻게 갈 수 있나요? IEEE 754 부동 소수점은 소수점 이하 15 자리의 정밀도를 얻을 수있는 소수에 대해 52 비트 만 있습니다. 바이너리로 저장됩니다. 십진법 해석이 더 많은 것을 저장하는 이유는 무엇입니까?


MinGW g ++ (및 gcc) 7.3.0을 사용하면 결과가 정확하게 재현됩니다.

이것은 Undefined Behavior의 매우 이상한 경우입니다.

정의되지 않은 동작은 printf적절한 헤더를 포함하지 않고 사용하여 ¹ "shall"을

C ++ 17 §20.5.2.2

번역 단위는 선언 또는 정의 외부에만 헤더를 포함해야하며 해당 헤더에 선언 된 엔티티에 대한 해당 번역 단위의 첫 번째 참조 앞에 어휘 적으로 헤더를 포함해야합니다. 진단이 필요하지 않습니다.

는 C ++ 코드 변경에 <iostream><stdio.h>, 얻을 유효한 C ++ 코드를 , 당신은 C 프로그램과 동일한 결과를 얻을.


C ++ 코드가 컴파일되는 이유는 무엇입니까?

음, C와 달리 C ++에서는 표준 라이브러리 헤더를 다른 헤더로 드래그 할 수 있습니다. 그리고 분명히 g ++를 사용하면 <iostream>헤더가 printf. 완전히 올바른 것은 아닙니다.

세부 사항 : MinGW g ++ 7.3.0에서 선언 / 정의 printf는 매크로 기호 따라 다릅니다 __USE_MINGW_ANSI_STDIO. 디폴트는 것입니다 <stdio.h>선언합니다 printf. 그러나이 __USE_MINGW_ANSI_STDIO논리적 true로 <stdio.h>정의되면를 printf호출 하는의 재정의 정의를 제공 합니다 __mingw_vprintf. 그리고 그것은 발생로 <cstdio>(간접적 포함 통해) 헤더를 정의를 __USE_MINGW_ANSI_STDIO포함하기 전에 <stdio.h>.

<_mingw.h>"C ++에서 _GNU_SOURCE에 대해서도 활성화하지만 C의 경우에는 활성화하지 않습니다." 라는 주석이 있습니다 .

C ++에서이 컴파일러의 해당 버전으로, 효과적으로 포함 사이에 차이가 <stdio.h>및 사용 printf, 또는 포함 <cstdio>, 말 using std::printf;, 및 사용 printf.


에 관해서

또한 어떻게 소수점 55 자리까지 갈 수 있을까요? IEEE 754 부동 소수점은 소수점 이하 15 자리의 정밀도를 얻을 수있는 소수에 대해 52 비트 만 있습니다. 바이너리로 저장됩니다. 십진법 해석은 왜 더 많은 것을 저장합니까?

... 그것은 더 긴 십진수 표현 일뿐 입니다. 내부 표현의 정밀도를 넘어서는 숫자 (64 비트 IEEE 754의 경우 약 15 자리)는 기본적으로 가비지이지만 원래 비트를 정확하게 재구성하는 데 사용할 수 있습니다. 어느 시점에서 그것들은 모두 0이 될 것이고, 그 지점은 C ++ 프로그램 출력의 마지막 숫자에 도달합니다.


1 표준 견적을 찾은 Dietrich Epp 에게 감사드립니다 .


두 경우 모두 십진수 56 자리를 인쇄하는 것처럼 보이므로이 질문은 기술적으로 결함이있는 전제를 기반으로합니다.

또한 두 숫자가 모두 0.152 비트의 정밀도 내에서 동일 하므로 둘 다 정확합니다.

그것은 당신의 마지막 질문으로 이어집니다. "어떻게 그것의 소수 해석이 더 많은 것을 저장 하는가?". 더 많은 소수를 저장 하지 않습니다 . double소수를 저장하지 않습니다. 그것은 비트를 저장합니다. 소수가 생성됩니다.

참고 URL : https://stackoverflow.com/questions/52660296/why-does-double-in-c-print-fewer-decimal-digits-than-c

반응형