【发布时间】:2018-03-07 15:48:52
【问题描述】:
好吧,所以我试图从具有给定位数精度(前后的总位数,或没有小数)的双精度数中截断实际值,而不仅仅是输出它们,而不仅仅是四舍五入。我为此找到的唯一内置函数会截断所有小数,或四舍五入到给定的小数精度。 我在网上找到的其他解决方案,只有在您知道小数点前的位数或整数时才能这样做。 该解决方案应该足够动态以处理任何数字。我编写了一些代码来完成下面的技巧,但是我无法摆脱这种感觉有更好的方法来做到这一点。有谁知道更优雅的东西?也许是我不知道的内置函数?
我应该提一下这样做的原因。观测值有 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());
}
【问题讨论】:
-
如果您知道如何舍入/截断小数点后的第一个数字,并且知道如何乘以/除以 10,那么您可以舍入/截断您喜欢的任何数字
-
(num * pow(10, n)) / pow(10, n)会做你想做的事,但有些数字不能准确表达,所以你仍然可以得到更多的值。这样做的实际目的是什么?几乎听起来你想要一个定点库。 -
浮点数并不是这样工作的。我会考虑使用具有 2 个整数的 Decimal 类型,一个是尾数,另一个是指数。稍后将它们操作到您想要的任何精度都非常简单:将尾数除以 pow(10,n),将 n 添加到指数
-
@tobi303 是的,我考虑过采用迭代方法除以或乘以 10,但我认为字符串可能更快。必须测试它XD
-
@EyalK。听起来很酷 =) 我唯一的问题是,与我提供的代码相比有什么优势?为了得到尾数,无论如何我都必须操纵双精度来移动小数。然后我必须存储两个代表一个的变量。总而言之,这听起来像是额外的代码行来完成同样的事情。不过我可能会遗漏一些东西..
标签: c++ set double precision truncate