Làm cách nào để in một double
giá trị với độ chính xác đầy đủ bằng cout?
Sử dụng hexfloat
hoặc
sử dụng scientific
và thiết lập độ chính xác
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
Quá nhiều câu trả lời chỉ giải quyết một trong 1) cơ sở 2) bố cục cố định / khoa học hoặc 3) chính xác. Quá nhiều câu trả lời với độ chính xác không cung cấp giá trị phù hợp cần thiết. Do đó câu trả lời cho một câu hỏi cũ.
- Cơ sở nào?
A double
chắc chắn được mã hóa bằng cơ sở 2. Cách tiếp cận trực tiếp với C ++ 11 là in bằng cách sử dụng std::hexfloat
.
Nếu một đầu ra không thập phân được chấp nhận, chúng ta đã hoàn thành.
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
- Nếu không:
fixed
hay scientific
?
A double
là loại điểm nổi , không phải điểm cố định .
Đừng không sử dụng std::fixed
như thất bại trong việc in nhỏ double
như bất cứ điều gì nhưng 0.000...000
. Đối với lớn double
, nó in nhiều chữ số, có thể hàng trăm thông tin nghi vấn.
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
Để in với độ chính xác đầy đủ, trước tiên, sử dụng std::scientific
sẽ "ghi các giá trị dấu phẩy động theo ký hiệu khoa học". Lưu ý mặc định là 6 chữ số sau dấu thập phân, một lượng không đủ, được xử lý ở điểm tiếp theo.
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
- Độ chính xác bao nhiêu (bao nhiêu chữ số)?
Một double
mã hóa sử dụng cơ sở nhị phân 2 mã hóa cùng độ chính xác giữa các quyền hạn khác nhau của 2. Đây thường là 53 bit.
[1.0 ... 2.0) có 2 53 khác nhau double
,
[2.0 ... 4.0) có 2 53 khác nhau double
,
[4.0 ... 8.0) có 2 53 khác nhau double
,
[8.0 ... 10.0) có 2 / 8 * 2 53 khác nhau double
.
Tuy nhiên, nếu mã bản in trong hệ thập phân với N
chữ số có nghĩa, số kết hợp [1.0 ... 10.0) là 9/10 * 10 N .
Dù N
lựa chọn (độ chính xác) là gì, sẽ không có ánh xạ một-một giữadouble
văn bản thập phân. Nếu một cố định N
được chọn, đôi khi nó sẽ hơi nhiều hơn hoặc ít hơn mức thực sự cần thiết cho các double
giá trị nhất định . Chúng tôi có thể lỗi trên quá ít ( a)
bên dưới) hoặc quá nhiều ( b)
bên dưới).
3 thí sinh N
:
a) Sử dụng một N
như vậy khi chuyển đổi từ văn bản - văn bản, double
chúng tôi đến cùng một văn bản cho tất cả double
.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) Sử dụng N
như vậy khi chuyển đổi từ double
-text-double
chúng tôi đến cùng double
cho tất cả double
.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
Khi max_digits10
không có sẵn, lưu ý rằng do thuộc tính cơ sở 2 và cơ sở 10 digits10 + 2 <= max_digits10 <= digits10 + 3
, chúng tôi có thể sử dụng digits10 + 3
để đảm bảo đủ các chữ số thập phân được in.
c) Sử dụng một N
thay đổi với giá trị.
Điều này có thể hữu ích khi mã muốn hiển thị văn bản tối thiểu ( N == 1
) hoặc giá trị chính xác của một double
( N == 1000-ish
trong trường hợpdenorm_min
). Tuy nhiên, vì đây là "công việc" và không có khả năng là mục tiêu của OP, nên nó sẽ được đặt sang một bên.
Nó thường là b) được sử dụng để "in một double
giá trị với độ chính xác đầy đủ". Một số ứng dụng có thể thích a) lỗi khi không cung cấp quá nhiều thông tin.
Với .scientific
, .precision()
đặt số chữ số sẽ in sau dấu thập phân, để 1 + .precision()
chữ số được in. Mã cần max_digits10
tổng số chữ số để .precision()
được gọi với a 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âu hỏi C tương tự
fixed
? Vớidouble h = 6.62606957e-34;
,fixed
cho tôi0.000000000000000
vàscientific
đầu ra6.626069570000000e-34
.