c++ - C++ 中的有效数字

标签 c++ iomanip significant-digits

我编写了一个程序来计算一系列值,并且所有值都是特别长的 double 。我想打印这些值,每个值显示 15 位有效数字。下面是一些代码,说明了我遇到的问题:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    double x = 0.12345678901234567890;
    double y = 1.12345678901234567890;
    cout << setprecision(15) << fixed << x << "\t" << y << "\n";
    return 0;
}

仅设置精度后缀零不会显示,因此我添加了固定值,正如我在本网站的其他答案中看到的那样。然而,现在我似乎只有 15 位小数,对于非 0 的值,这不是我想要的。您可以从上面的输出中看到这一点:

0.123456789012346       1.123456789012346

第一个数字有 15 个数字,但第二个数字有 16 个数字。我该怎么解决这个问题?

编辑:我被特别要求使用 set precision,所以我无法尝试 cout. precision。

最佳答案

您可以简单地使用科学(注意 14 而不是 15):

std::cout << std::scientific << std::setprecision(14) << -0.123456789012345678 << std::endl;
std::cout << std::scientific << std::setprecision(14) << -1.234567890123456789 << std::endl;

-1.23456789012346e-01
-1.23456789012346e+00

或者您可以使用函数:

#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include <sstream>

enum vis_opt { scientific, decimal, decimal_relaxed };

std::string figures(double x, int nfig, vis_opt vo=decimal) {
    std::stringstream str;

    str << std::setprecision(nfig-1) << std::scientific << x;
    std::string s = str.str();
    if ( vo == scientific )
        return s;
    else {
        std::stringstream out;
        std::size_t pos;

        int ileft = std::stoi(s,&pos);

        std::string dec = s.substr(pos + 1, nfig - 1);
        int e = std::stoi(s.substr(pos + nfig + 1));

        if ( e < 0 ) {
            std::string zeroes(-1-e,'0');
            if ( ileft < 0 ) 
                out << "-0." << zeroes << -ileft << dec;
            else
                out << "0." << zeroes << ileft << dec;
        } else if ( e == 0) {
            out << ileft << '.' << dec;
        } else if ( e < ( nfig - 1) ) {
            out << ileft << dec.substr(0,e) << '.' << dec.substr(e);
        } else if ( e == ( nfig - 1) ) {
            out << ileft << dec;
        } else {
            if ( vo == decimal_relaxed) {
                out << s;
            } else {
                out << ileft << dec << std::string(e - nfig + 1,'0');
            }
        }

        return out.str();   
    }

}

int main() {
    std::vector<double> test_cases = {
        -123456789012345,
        -12.34567890123456789,
        -0.1234567890123456789,
        -0.0001234,
        0,
        0.0001234,
        0.1234567890123456789,
        12.34567890123456789,
        1.234567890123456789,
        12345678901234,
        123456789012345,
        1234567890123456789.0,
    };


    for ( auto i : test_cases) {
        std::cout << std::setw(22) << std::right << figures(i,15,scientific);
        std::cout << std::setw(22) << std::right << figures(i,15) << std::endl;
    }
    return 0;
}

我的输出是:

 -1.23456789012345e+14      -123456789012345
 -1.23456789012346e+01     -12.3456789012346
 -1.23456789012346e-01    -0.123456789012346
 -1.23400000000000e-04 -0.000123400000000000
  0.00000000000000e+00      0.00000000000000
  1.23400000000000e-04  0.000123400000000000
  1.23456789012346e-01     0.123456789012346
  1.23456789012346e+01      12.3456789012346
  1.23456789012346e+00      1.23456789012346
  1.23456789012340e+13      12345678901234.0
  1.23456789012345e+14       123456789012345
  1.23456789012346e+18   1234567890123460000

关于c++ - C++ 中的有效数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33658851/

相关文章:

r - 使用 round() 后跟 signif() 进行连续舍入后的尾随零

python - 在 NumPy 中提取浮点有效数和指数

c++ - OpenCL 视频处理

c++ - C++初始化二维数组

c++ - "std::cout << std::endl;"如何编译?

c++ - 将格式化的 char 数组发送到 ostream 而无需额外的内存复制

c++ - C++中的VTable是什么时候创建的?

c++ - 基于通过/失败返回改变 MFC 对话框中的 LED 颜色

c++ - 如何打印长双(全长)C++

java - 根据 BigDecimals 的有效数字比较 BigDecimals 是否接近可接受