C ++设置double的精度(不用于输出)

时间:2017-09-26 12:08:57

标签: c++ set double precision truncate

好吧所以我试图从具有给定位数精度的双精度(前后总数或不带十进制数)中截取实际值,而不仅仅是输出它们,而不仅仅是围绕它们。我找到的唯一内置函数会截断所有小数,或舍入到给定的小数精度。 我在网上找到的其他解决方案,只有当您知道小数点前的位数或整数时才能这样做。 该解决方案应该足够动态以处理任何数字。我掀起了一些代码来完成下面的技巧,但我无法感觉有更好的方法来做到这一点。有谁知道更优雅的东西?也许是我不了解的内置功能?

我应该提到这个的原因。有3种不同的观察值来源。所有这三个来源都达到了一定程度的精确度。如下所示,他们都在10位数内达成一致。     4659.96751751236     4659.96751721355     4659.96751764253 但是我只需要从其中一个来源中提取。所以最好的方法,就是只使用最高精度的所有3个来源达成一致。所以它不像我操纵数字然后需要截断精度,它们是观察值。期望的结果是 4659.967517

double truncate(double num,int digits) {

// check valid digits
if (digits < 0)
    return num;

// create string stream for full precision (string conversion rounds at 10)
ostringstream numO;

// read in number to stream, at 17+ precision things get wonky
numO << setprecision(16) << num;

// convert to string, for character manipulation
string numS = numO.str();

// check if we have a decimal
int decimalIndex = numS.find('.');

// if we have a decimal, erase it for now, logging its position
if(decimalIndex != -1)
    numS.erase(decimalIndex, 1);

// make sure our target precision is not higher than current precision
digits = min((int)numS.size(), digits);

// replace unwanted precision with zeroes
numS.replace(digits, numS.size() - digits, numS.size() - digits, '0');

// if we had a decimal, add it back
if (decimalIndex != -1)
    numS.insert(numS.begin() + decimalIndex, '.');

return atof(numS.c_str());

}

2 个答案:

答案 0 :(得分:4)

由于double 不是十进制类型,因此无法使用。截断你认为是一定数量的十进制数字只会在结尾处引入一组新的笑话数字。它甚至可能是有害的:例如0.125完全是double,但0.120.13都不是。

如果你想以小数形式工作,那么使用小数类型或大型整数类型,其约定部分包含小数部分。

答案 1 :(得分:0)

我不同意&#34;所以最好的方法是仅使用所有3个来源同意的精确度。&#34;

如果这些是物理量的不同测量值,或者由于测量计算的不同方式而表示舍入误差,则通过取平均值而不是通过强制它们不同意的数字来获得对真实值的更好估计。任意值,包括零。

取平均值的最终理由是Central Limit Theorem,这表明将测量值视为正态分布的样本。如果是这样,样本均值是人口平均值的最佳可用估计值。截断过程往往会低估实际值。

通常最好保留计算中的每一条信息,然后记住输出结果时精度有限。

除了给出更好的估计之外,取三个数的平均值是一个非常简单的计算。