كيف يمكنني طباعة قيمة مزدوجة بدقة كاملة باستخدام cout؟

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

سؤال

لذلك حصلت على الجواب على بلدي السؤال الأخير (لا أعرف لماذا لم أفكر في ذلك).كنت أطبع أ double استخدام cout التي تم تقريبها عندما لم أكن أتوقع ذلك.كيف يمكنني أن أجعل cout طباعة أ double باستخدام الدقة الكاملة؟

هل كانت مفيدة؟

المحلول

يمكنك ضبط الدقة مباشرة على std::cout واستخدام std::fixed تنسيق محدد.

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

يمكنك #include <limits> للحصول على أقصى دقة من تعويم أو مزدوج.

#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;

أساسا حزمة الحدود لديها سمات لجميع البناء في أنواع.
واحدة من سمات أرقام النقطة العائمة (تعويم / مزدوج / طويل مزدوج) هي سمة أرقام 10. هذا يحدد الدقة (نسيت المصطلحات الدقيقة) لرقم نقطة عائمة في قاعدة 10.

يرى: http://www.cplusplus.com/Reference/std/limits/numeric_limits.html.
للحصول على تفاصيل حول السمات الأخرى.

طريقة iOStreams هي نوع من clunky. انا افضل 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;

انتاج:

PI: 3.14159265358979.

إليك كيفية عرض مزدوج بدقة كاملة:

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 عدد الأرقام قبل وبعد النقطة العشرية.


لا تستخدم SET_PRECISION (MAX_DIGITS10) مع STD :: ثابت.
على التدوين الثابت، 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 بالضبط.الطريقة الوحيدة للحصول على ممتلئ ممتلئ دقة المضاعفة الفعلية (مع عدم وجود خطأ في التقريب) هي طباعة البتات الثنائية (أو القضم السداسي).إحدى الطرق للقيام بذلك هي كتابة double إلى أ union ومن ثم طباعة القيمة الصحيحة للبتات.

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

سيعطيك هذا دقة دقيقة بنسبة 100٪ للمضاعفة ...ويكون غير قابل للقراءة على الإطلاق لأن البشر لا يستطيعون قراءة تنسيق IEEE المزدوج! ويكيبيديا لديه كتابة جيدة حول كيفية تفسير البتات الثنائية.

في الإصدار الأحدث من C++، يمكنك القيام بذلك

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

كيف يمكنني طباعة double القيمة مع الدقة الكامل باستخدام cout؟

يستخدم 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. ما قاعدة؟

أ double من المؤكد أن تشفير باستخدام قاعدة 2. النهج المباشر مع C ++ 11 هو الطباعة باستخدام std::hexfloat.
إذا كان الإخراج غير العشري مقبول، فقد انتهينا.

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?

أ double هو النقطة العائمة اكتب، لا نقطة ثابتة.

يفعل ليس استعمال std::fixed كما يفشل في طباعة صغيرة double بأي شيء سوى ذلك 0.000...000. وبعد لكبير double, ، يطبع العديد من الأرقام، ربما مئات من المعلومات المشكوك فيها.

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 ترميز نفس الدقة بين السلطات المختلفة 2. هذا غالبا 53 بت.

1.0 ... 2.0) هناك 253 مختلف double,
2.0 ... 4.0) هناك 253 مختلف double,
4.0 ... 8.0) هناك 253 مختلف double,
8.0 ... 10.0) هناك 2/8 * 253 مختلف double.

ولكن إذا طباعت التعليمات البرمجية في عشري N أرقام مهمة، عدد المجموعات [1.0 ... 10.0) هو 9/10 * 10ن.

ما من أي وقت مضى N (الدقة) يتم اختياره، لن يكون هناك رسم خرائط فردية بين double والنص العشري. إذا تم إصلاحها N يتم اختيارها، وأحيانا ستكون أكثر أو أقل قليلا من اللازمة حقا لبعض double القيم. يمكن أن نخرأ على عدد قليل جدا (a) أدناه) أو الكثير جدا (b) أقل).

3 مرشح N:

أ) استخدام N لذلك عند التحويل من النصdouble- نتصل وصلنا إلى نفس النص للجميع double.

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

ب) استخدام N لذلك عند التحويل من double-نص-double وصلنا إلى نفسه double للجميع double.

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

متي max_digits10 غير متوفر، لاحظ أنه بسبب قاعدة 2 و 10 سمات 10، digits10 + 2 <= max_digits10 <= digits10 + 3, ، يمكننا ان نستخدم digits10 + 3 لضمان ما يكفي من الأرقام العشرية المطبوعة.

ج) استخدام N هذا يختلف مع القيمة.

قد يكون هذا مفيدا عندما يريد التعليمات البرمجية عرض النص الأدنى (N == 1) أو ال بالضبط قيمة أ double (N == 1000-ish في حالة ما اذا denorm_min). ومع ذلك، لأن هذا هو "العمل" وليس هدف OP المرجح، فسيتم تخصيصه جانبا.


عادة ما يكون ب) يستخدم "طباعة أ double القيمة مع الدقة الكامل ". قد تفضل بعض التطبيقات أ) عن الخطأ على عدم توفير الكثير من المعلومات.

مع .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

ج سؤال مماثل

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

٪ .12F يعني النقطة العائمة، بدقة 12 رقما.

Cout هو كائن يحتوي على مجموعة من الطرق التي يمكنك الاتصال بها لتغيير الدقة وتنسيق الأشياء المطبوعة.

هناك عملية SetPrecision (...)، ولكن يمكنك أيضا تعيين أشياء أخرى مثل عرض الطباعة، إلخ.

ابحث عن cout في مرجع IDE الخاص بك.

الأكثر جدة ...

#include <limits>

using std::numeric_limits;

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

مع Ostream :: الدقة (int)

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

سوف تسفر

3.141592653589793, 2.718281828459045

لماذا عليك أن تقول "+1" ليس لدي أدنى فكرة، لكن الرقم الإضافي الذي تخرج منه هو الصحيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top