[c++] 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밑이 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;


답변

완전 정밀도로 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>


답변

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는 확실히 base 2를 사용하여 인코딩됩니다. C ++ 11을 사용한 직접적인 접근 방식은을 사용하여 인쇄하는 것 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. 얼마나 많은 정밀도 (총 자릿수)?

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 질문