简体   繁体   English

C ++将精度设置为双精度(不用于输出)

[英]C++ set precision of a double (not for output)

Alright so I am trying to truncate actual values from a double with a given number of digits precision (total digits before and after, or without, decimal), not just output them, not just round them. 好吧,所以我试图以给定的数字精度(不包括小数点之前和之后的总位数,或不包括小数的位数)从双精度中截断实际值,而不仅仅是输出它们,而不仅仅是四舍五入。 The only built in functions I found for this truncates all decimals, or rounds to given decimal precision. 我为此找到的唯一内置函数会截断所有小数,或舍入到给定的十进制精度。 Other solutions I have found online, can only do it when you know the number of digits before the decimal, or the entire number. 我在网上找到的其他解决方案,只有在您知道小数点前的位数或整数时才能使用。 This solution should be dynamic enough to handle any number. 此解决方案应具有足够的动态性以处理任意数量的数据。 I whipped up some code that does the trick below, however I can't shake the feeling there is a better way to do it. 我整理了一些实现下面这些技巧的代码,但是我不能动摇有更好的方法来做。 Does anyone know of something more elegant? 有人知道更优雅的东西吗? Maybe a built in function that I don't know about? 也许是我不知道的内置函数?

I should mention the reason for this. 我应该提到原因。 There are 3 different sources of observed values. 有3种不同的观测值来源。 All 3 of these sources agree to some level in precision. 所有这三个来源在精度上都达到了一定水平。 Such as below, they all agree within 10 digits. 如下所示,他们都同意10位数以内。 4659.96751751236 4659.96751721355 4659.96751764253 However I need to only pull from 1 of the sources. 4659.96751751236 4659.96751721355 4659.96751764253但是我只需要从1个来源中提取即可。 So the best approach, is to only use up to the precision all 3 sources agree on. 因此,最好的方法是仅使用所有三个源都同意的精度。 So its not like I am manipulating numbers and then need to truncate precision, they are observed values. 所以它不像我在操纵数字,然后需要截断精度,它们是观测值。 The desired result is 4659.967517 期望的结果是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());

} }

This will never work since a double is not a decimal type. 因为double精度数不是十进制类型,所以它将永远无法工作。 Truncating what you think are a certain number of decimal digits will merely introduce a new set of joke digits at the end. 截断您认为一定数量的十进制数字只会在末尾引入一组新的笑话数字。 It could even be pernicious: eg 0.125 is an exact double , but neither 0.12 nor 0.13 are. 它甚至可能是有害的:例如0.125是精确的double ,但0.120.13都不是。

If you want to work in decimals, then use a decimal type, or a large integral type with a convention that part of it holds a decimal portion. 如果要使用小数,请使用小数类型或大整数类型,并且约定其中一部分包含小数部分。

I disagree with "So the best approach, is to only use up to the precision all 3 sources agree on." 我不同意“因此,最好的方法是仅使用所有三个来源都同意的精度”。

If these are different measurements of a physical quantity, or represent rounding error due to different ways of calculating from measurements, you will get a better estimate of the true value by taking their mean than by forcing the digits they disagree about to any arbitrary value, including zero. 如果这些是对物理量的不同度量,或者由于不同的计算方式而导致四舍五入误差,那么通过取其均值,而不是将它们不同意的数字强制为任意值,您将更好地估计真实值,包括零。

The ultimate justification for taking the mean is the Central Limit Theorem , which suggests treating your measurements as a sample from a normal distribution. 取均值的最终理由是中央极限定理 ,它建议将您的测量值视为正态分布的样本。 If so, the sample mean is the best available estimate of the population mean. 如果是这样,则样本均值是总体均值的最佳可用估计值。 Your truncation process will tend to underestimate the actual value. 您的截断过程会低估实际值。

It is generally better to keep every scrap of information you have through the calculations, and then remember you have limited precision when outputting results. 通常最好保留计算过程中掌握的每条信息,然后记住输出结果时精度有限。

As well as giving a better estimate, taking the mean of three numbers is an extremely simple calculation. 除了给出更好的估计之外,取三个数字的平均值也是一个非常简单的计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM