Programing

cout을 사용하여 배정 밀도로 double 값을 인쇄하는 방법은 무엇입니까?

lottogame 2020. 3. 14. 10:03
반응형

cout을 사용하여 배정 밀도로 double 값을 인쇄하는 방법은 무엇입니까?


그래서 나는 마지막 질문에 대한 답을 얻었습니다 (왜 그런 생각을하지 않았는지 모르겠습니다). 나는 인쇄 된 double사용 cout나는 그것을 기대하지 않은 때 GOT가 반올림. 완전 정밀도로 cout인쇄하려면 어떻게 double해야합니까?


정밀도를 직접 설정 std::cout하고 std::fixed형식 지정자를 사용할 수 있습니다 .

double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;

#include <limits>float 또는 double의 최대 정밀도를 얻을 수 있습니다 .

#include <limits>

typedef std::numeric_limits< double > dbl;

double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;

사용 std::setprecision:

std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;

다음은 내가 사용하는 것입니다.

std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
          << 3.14159265358979
          << std::endl;

기본적으로 limits 패키지에는 모든 빌드 유형에 대한 특성이 있습니다.
부동 소수점 숫자 (float / double / long double)의 특성 중 하나는 numeric10 속성입니다. 이것은 밑 10의 부동 소수점 숫자의 정확성을 정의합니다 (정확한 용어를 잊어 버렸습니다).

다른 속성에 대한 자세한 내용은 http://www.cplusplus.com/reference/std/limits/numeric_limits.html을 참조하십시오
.


iostreams 방식은 어색합니다. 나는 boost::lexical_cast그것이 나에게 올바른 정밀도를 계산하기 때문에 사용하는 것을 선호합니다 . 그리고 그것은 또한 빠릅니다 .

#include <string>
#include <boost/lexical_cast.hpp>

using boost::lexical_cast;
using std::string;

double d = 3.14159265358979;
cout << "Pi: " << lexical_cast<string>(d) << endl;

산출:

파이 : 3.14159265358979


완전 정밀도로 double을 표시하는 방법은 다음과 같습니다.

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;

다음이 표시됩니다.

100.0000000000005


max_digits10은 고유 한 모든 이중 값을 고유하게 나타내는 데 필요한 자릿수입니다. max_digits10은 소수점 전후 자릿수를 나타냅니다.


std :: fixed와 함께 set_precision (max_digits10)을 사용하지 마십시오.
고정 표기법에서 set_precision () 은 소수점 뒤에 만 자릿수를 설정합니다 . max_digits10이 자리의 수를 나타냅니다 이것은 잘못된 이전이후에 소수점.

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;

잘못된 결과가 표시됩니다.

100.00000000000049738

참고 : 헤더 파일이 필요합니다

#include <iomanip>
#include <limits>

완전 정밀도로, 나는 의도 된 값에 가장 가까운 근사치를 표시하기에 충분한 정밀도를 가정하지만, double밑이 2를 사용하여 저장되고 밑이 2가 1.1정확하게 사소한 것을 나타낼 수 없다는 것이 지적되어야합니다 . 실제 배정도의 완전 정밀도 를 얻는 유일한 방법은 (NO ROUND OFF ERROR 포함) 이진 비트 (또는 16 진 nybbles)를 인쇄하는 것입니다. 이를 수행하는 한 가지 방법은 double에 a를 union다음 비트의 정수 값을 인쇄하는 것입니다.

union {
    double d;
    uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;

이것은 당신에게 double의 100 % 정확한 정밀도를 줄 것입니다 ... 그리고 인간은 IEEE double 형식을 읽을 수 없기 때문에 완전히 읽을 수 없습니다! Wikipedia 에는 이진 비트를 해석하는 방법에 대한 훌륭한 글이 있습니다.

최신 C ++에서는 할 수 있습니다

std::cout << std::hexfloat << 1.1;

doublecout을 사용하여 완전 정밀도 값을 인쇄하는 방법은 무엇입니까?

정밀도 사용 hexfloat또는
사용 scientific및 설정

std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific <<  1.0/7.0 << '\n';

// C++11 Typical output
1.4285714285714285e-01

답변이 너무 많으면 1) 기본 2) 고정 / 과학 레이아웃 또는 3) 정밀도 중 하나만 처리합니다. 너무 정확한 답변이 필요한 값을 제공하지 않습니다. 따라서 이것은 오래된 질문에 대한 대답입니다.

  1. 어떤 기지?

A double는 확실히베이스 2를 사용하여 인코딩됩니다 std::hexfloat.
10 진이 아닌 출력이 허용되면 완료됩니다.

std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144

  1. 그렇지 않으면 : fixed또는 scientific?

A double고정 소수점이 아닌 부동 소수점 유형 입니다.

작은 것만 인쇄 할 수 없으므로 사용 하지 마십시오 . 경우 많은 숫자, 아마도 수백 개의 의심스러운 정보를 인쇄 합니다.std::fixeddouble0.000...000double

std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000 

완전 정밀도로 인쇄하려면 먼저 std::scientific"과학 표기법으로 부동 소수점 값을 작성합니다"를 사용하십시오. 소수점 이하의 기본값 인 6 자리 (불충분 한 금액)는 다음 포인트에서 처리됩니다.

std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';  
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43

  1. 얼마나 많은 정밀도 (총 자릿수)?

A는 double이진베이스 2 인코딩이 종종 53 비트 (2)의 각종 능력과 동일한 정밀도를 사용하여 인코딩.

[1.0 ... 2.0) 2 53 가지가 double있고,
[2.0 ... 4.0) 2 53 가지가 double있고,
[4.0 ... 8.0) 2 53 가지가 double있고,
[8.0 ... 10.0) 2 /가있다 8 * 2 53 다른 double.

그러나 코드가 N유효 숫자 로 10 진수로 인쇄되는 경우 조합 수 [1.0 ... 10.0)는 9/10 * 10 N 입니다.

어떤 N(정밀)을 선택 하든지 double, 십진 텍스트 사이에는 일대일 매핑이 없습니다 . 고정 N을 선택하면 때로는 특정 double값에 필요한 것보다 약간 많거나 적을 수 있습니다 . 너무 적 a)거나 ( 아래) 너무 많거나 ( 아래) 오류가 발생할 수 b)있습니다.

3 후보 N:

a) text-text에서 N변환 할 때 so를 사용하여 double모두 같은 텍스트에 도착합니다 double.

std::cout << dbl::digits10 << '\n';
// Typical output
15

b)는을 사용하여 N변환 할 때 너무 double-text- double우리가 같은 도착 double모든 double.

// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17

max_digits10사용할 수 없습니다 때문에베이스 2베이스 (10 개)의 속성에 있습니다 digits10 + 2 <= max_digits10 <= digits10 + 3, 우리가 사용할 수있는 digits10 + 3충분한 진수를 보장하기 위해 인쇄됩니다.

c) N값에 따라 다른를 사용하십시오 .

코드는 최소한의 텍스트 (표시하고자 할 때 유용 할 수 있습니다 N == 1) 또는 정확한 의 값 double( N == 1000-ish의 경우를 denorm_min). 그러나 이것이 "작업"이고 OP의 목표가 아닐 가능성이 있기 때문에 제외 될 것입니다.


일반적으로 b) " double전체 정밀도 값을 인쇄"하는 데 사용됩니다 . 일부 응용 프로그램은 정보를 너무 많이 제공하지 않으면 a) 오류를 선호 할 수 있습니다.

함께 .scientific, .precision()그래서 세트 자릿수, 소수점 후 인쇄 1 + .precision()숫자가 인쇄된다. 코드에는 max_digits10총 자릿수 .precision()필요 하므로 로 호출됩니다 max_digits10 - 1.

typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific <<  exp (-100) << '\n';
std::cout << std::scientific <<  exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43
//1234567890123456  17 total digits

비슷한 C 질문


printf("%.12f", M_PI);

% .12f는 12 자리의 정밀도로 부동 소수점을 의미합니다.


cout은 인쇄물의 정밀도와 형식을 변경하기 위해 호출 할 수있는 많은 메소드가있는 객체입니다.

setprecision (...) 연산이 있지만 인쇄 너비 등과 같은 다른 항목도 설정할 수 있습니다.

IDE 참조에서 cout을 찾으십시오.


가장 이식성있는 ...

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;

ostream :: precision (int) 사용

cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;

생산할 것이다

3.141592653589793, 2.718281828459045

왜 "+1"이라고 말해야하는지 모르겠습니다. 단, 추가 자리수는 맞습니다.

참고 URL : https://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout

반응형