긴 이중 출력의 정밀도는 정확하지 않습니다. 무엇이 잘못되었을 수 있습니까?

StackOverflow https://stackoverflow.com/questions/684112

문제

나는있다 long double 내가 const 또는 const로 설정하고 있다고 상수. A의 정밀도보다 길다 (40 자리) long double 내 테스트 워크 스테이션 (19 자리)에서.

인쇄하면 더 이상 정밀도 19 자리가 아니라 16 숫자로 표시됩니다.

내가 테스트하는 코드는 다음과 같습니다.

#include <iostream>
#include <iomanip>
#include <limits>
#include <cstdio>

int main ()
{
    const long double constLog2 = 0.6931471805599453094172321214581765680755;
    long double log2 = 0.6931471805599453094172321214581765680755;    

    std::cout << std::numeric_limits<long double>::digits10 + 1 << std::endl;
    std::cout << "const via cout: " << std::setprecision(19) << constLog2 << std::endl;
    std::cout << "non-const via cout: " << std::setprecision(19) << log2 << std::endl;
    std::fprintf(stdout, "const via printf: %.19Lf\n", constLog2);
    std::fprintf(stdout, "non-const via printf: %.19Lf\n", log2);

    return 0;
}

엮다:

$ g++ -Wall precisionTest.cpp

산출:

$ ./a.out
19
const via cout: 0.6931471805599452862
non-const via cout: 0.6931471805599452862
const via printf: 0.6931471805599452862
non-const via printf: 0.6931471805599452862

나는 기대할 것이다 0.6931471805599453094 그러나 대신 얻습니다 0.6931471805599452862.

19 자리 숫자의 정밀도가 16 자리로 절단되는 이유가 있습니까?

여기 내 환경이 있습니다.

$ gcc --version
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)

다른 버전의 GCC와 같은 문제가 있습니다.

$ gcc --version
g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-10)

나는 NTL이나 다른 라이브러리를 살펴볼 수 있지만 이것을 일으키는 원인이 궁금합니다. 당신의 통찰에 감사드립니다.

도움이 되었습니까?

해결책

나는이 출력을 얻는다 :

19
const via cout: 0.6931471805599453094
non-const via cout: 0.6931471805599453094
const via printf: 0.6931471805599453094
non-const via printf: 0.6931471805599453094

그러나 나는 더블 리터럴 대신 긴 이중 리터럴을 사용하고 있습니다.

const long double constLog2 = 0.6931471805599453094172321214581765680755L;
long double log2 = 0.6931471805599453094172321214581765680755L;    

다른 팁

하드웨어 플랫폼 및 컴파일 옵션과 관련된 몇 가지 미묘한 문제가 있습니다.

이`-m '옵션은 i386 및 x86-64 컴퓨터 제품군에 대해 정의됩니다.

-M96 비트-더우블

-M128 비트-더우블

이 스위치는 긴 이중 유형의 크기를 제어합니다. i386 애플리케이션 바이너리 인터페이스는 크기를 96 비트로 지정하므로 -M96 비트-더우블은 32 비트 모드의 기본값입니다. 현대 아키텍처 (Pentium and Newer)는 8 또는 16 바이트 경계에 정렬되는 것을 선호합니다. ABI를 준수하는 배열 또는 구조에서는 불가능합니다. 따라서 -m128 비트-더우블을 지정하면 긴 더블을 추가로 32 비트 0으로 패딩하여 긴 더블을 16 바이트 경계에 정렬합니다.

X86-64 컴파일러에서 -M128 비트-더우블 더블은 ABI가 16 바이트 경계에서 긴 더블을 정렬해야한다고 지정함에 따라 기본 선택입니다.

이 옵션 중 어느 것도 X87 표준 80 비트에 대한 추가 정밀도를 제공하지 않습니다.

경고 : 대상 ABI의 기본값을 무시하면 긴 이중 변수가 포함 된 구조 및 배열이 크기가 변경되며 기능 호출 컨벤션이 긴 이중을 차지하는 기능이 수정됩니다. 따라서 해당 스위치없이 컴파일 된 코드의 배열 또는 구조와 이진 호환되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top