C++ 如何使用cout以全精度打印双精度值?

C++ 如何使用cout以全精度打印双精度值?,c++,floating-point,precision,iostream,cout,C++,Floating Point,Precision,Iostream,Cout,在我的工作中,我用cout打印了一个double,当我没有预料到的时候,它被舍入了。如何使cout使用全精度打印double?使用: std::cout使用: std::cout您可以直接在std::cout上设置精度,并使用格式说明符 double d = 3.14159265358979; cout.precision(17); cout << "Pi: " << fixed << d << endl; double d=3.14159265

在我的工作中,我用
cout
打印了一个
double
,当我没有预料到的时候,它被舍入了。如何使
cout
使用全精度打印
double

使用:

std::cout使用:


std::cout您可以直接在
std::cout
上设置精度,并使用格式说明符

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

cout您可以直接在
std::cout
上设置精度,并使用格式说明符

double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
double d=3.14159265358979;
计算精度(17);
最轻便的

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;
#包括
使用std::数值_限制;
...
计算精度(数值限制:数字10+1);
最轻便的

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;
#包括
使用std::数值_限制;
...
计算精度(数值限制:数字10+1);

cout以下是我将使用的:

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

std::cout以下是我将使用的:

std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
          << 3.14159265358979
          << std::endl;
带有ostream::precision(int)的std::cout

为什么要说“+1”我不知道,但从中得到的额外数字是正确的。

使用ostream::precision(int)

printf("%.12f", M_PI);
为什么你要说“+1”我不知道,但是你从中得到的额外数字是正确的

printf("%.12f", M_PI);
%.12f表示浮点,精度为12位


%.12f表示浮点,精度为12位。

iostreams方式有点笨重。我更喜欢使用,因为它为我计算了正确的精度。还有

#包括
#包括
使用boost::词法转换;
使用std::string;
双d=3.14159265358979;

coutiostreams的方式有点笨重。我更喜欢使用,因为它为我计算了正确的精度。还有

#包括
#包括
使用boost::词法转换;
使用std::string;
双d=3.14159265358979;

就全精度而言,我假设平均精度足以显示预期值的最佳近似值,但应该指出的是,
double
是使用base 2表示法存储的,base 2不能准确地表示
1.1
这样微不足道的值。获得实际双精度(无舍入误差)的满精度的唯一方法是打印二进制位(或十六进制nybles)

一种方法是使用
联合
双精度
键入一个整数,然后打印该整数,因为整数不会出现截断或舍入问题。这样的双关式不受C++标准的支持,但在C中是支持的。但是,大多数C++编译器可能会打印出正确的值。我认为G++支持这个。
联合{
双d;
uint64_t u64;
}x;
x、 d=1.1;

std::cout通过全精度,我假设平均精度足以显示与预期值的最佳近似值,但应该指出的是,
double
是使用base 2表示法存储的,base 2不能准确地表示
1.1
这样微不足道的内容。获得实际双精度(无舍入误差)的满精度的唯一方法是打印二进制位(或十六进制nybles)

一种方法是使用
联合
双精度
键入一个整数,然后打印该整数,因为整数不会出现截断或舍入问题。这样的双关式不受C++标准的支持,但在C中是支持的。但是,大多数C++编译器可能会打印出正确的值。我认为G++支持这个。
联合{
双d;
uint64_t u64;
}x;
x、 d=1.1;

std::cout以下是如何以全精度显示双精度:

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
double d=100.0000000000005;
整数精度=标准::数值限制::最大数字10;

std::cout以下是如何以全精度显示双精度:

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
double d=100.0000000000005;
整数精度=标准::数值限制::最大数字10;
标准::cout
如何使用cout以全精度打印一个
double

使用
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

  • 否则:
    固定
    科学
  • 双精度
    是浮点类型,而不是定点

    不要使用
    std::fixed
    ,因为它不能像
    0.000…000
    那样打印小的
    double
    。对于大的
    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 
    

  • 精度是多少(总位数是多少)
  • 使用二进制基数2编码的
    double
    在不同的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个不同的

    std::cout << dbl::digits10 << '\n';
    // Typical output
    15
    
    // C++11
    std::cout << dbl::max_digits10 << '\n';
    // Typical output
    17
    
    然而,如果代码以十进制形式打印,且带有
    N
    有效数字,则组合的数量[1.0…10.0]为9/10*10N

    无论选择什么
    N
    (精度),在
    double
    和十进制文本之间都不会有一对一的映射。
    如果选择一个固定的
    N
    ,有时它会稍微高于或低于某些
    double
    值的实际需要。我们可能会在太少(
    a)上出错
    以下)或太多(
    b)
    以下)

    3候选人
    N

    a) 使用
    N
    ,因此当从文本转换为双文本时,我们得到所有双文本的相同文本

    std::cout << dbl::digits10 << '\n';
    // Typical output
    15
    
    // C++11
    std::cout << dbl::max_digits10 << '\n';
    // Typical output
    17
    
    max_digits10
    不可用时,请注意,由于基数2和基数10属性,
    digits10+2
    如何使用cout以全精度打印一个
    double

    使用
    hexfloat

    使用
    scientific
    并设置
    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::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
    
    std::cout << dbl::digits10 << '\n';
    // Typical output
    15
    
    // C++11
    std::cout << dbl::max_digits10 << '\n';
    // Typical output
    17
    
    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
    
    #include <iostream>
    #include <iomanip>
    
    double d = 2.0;
    int n = 2;
    cout << fixed << setprecision(n) << d;
    
    cout << defaultfloat << d ;
    
    #include <limits>
    #include <iostream>
    
    template <class T>
    void printVal(std::ostream& os, T val)
    {
        auto oldFlags = os.flags();
        auto oldPrecision = os.precision();
    
        os.flags(oldFlags & ~std::ios_base::floatfield);
        os.precision(std::numeric_limits<T>::digits10);
        os << val;
        
        os.flags(oldFlags);
        os.precision(oldPrecision);
    }
    
    double d = foo();
    float f = bar();
    printVal(std::cout, d);
    printVal(std::cout, f);
    
    template <class T>
    struct PrintValWrapper { T val; };
    template <class T>
    std::ostream& operator<<(std::ostream& os, PrintValWrapper<T> pvw) {
        printVal(os, pvw.val);
        return os;
    }
    template <class T>
    PrintValWrapper<T> printIt(T val) {
        return PrintValWrapper<T>{val};
    }
    
    double d = foo();
    float f = bar();
    std::cout << "The values are: " << printIt(d) << ", " << printIt(f) << '\n';
    
    #include <format>
    #include <string>
    
    int main() {
        std::cout << std::format("{:.2} {:.3}\n", 3.1415, 3.1415);
    }
    
    3.14 3.145
    
    #include <format>
    #include <limits>
    #include <string>
    
    int main() {
        std::cout << std::format("{:.{}}\n",
            3.1415926535897932384626433, dbl::max_digits10);
    }
    
    std::cout << std::format("{}", M_PI);
    
    fmt::print("{}", M_PI);