在C ++中截断十进制值

时间:2008-11-20 00:48:26

标签: c++ decimal truncate

将值为0.6000002的C ++ float变量截断为0.6000并将其存储回变量的最简单方法是什么?

10 个答案:

答案 0 :(得分:12)

为什么发生这种情况的好参考资料可以在David Goldberg的What Every Computer Scientist Should Know About Floating Point Arithmetic中找到。

答案 1 :(得分:7)

首先,重要的是要知道浮点数是近似的。请参阅@Greg Hewgill提供的链接,了解为什么此问题无法完全解决。

但是这里有几个可能满足您需求的解决方案:

可能是更好的方法但效率更低:

char sz[64];
double lf = 0.600000002;
sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000

double lf2 = atof(sz);

//lf == 0.600000002;
//lf2 == 0.6000

printf("%.4lf", lf2); //print 0.6000

效率更高的方式,但可能不太精确:

double lf = 0.600000002;
int iSigned = lf > 0? 1: -1;
unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
lf = (((double)uiTemp)/pow(10,4) * iSigned);

答案 2 :(得分:6)

实际上这是不可能的。它不是C ++的限制,而只是浮点的工作方式。对于许多值,没有精确的表示,因此您不能简单地截断为多个数字。

使用printf格式字符串打印时可能会截断。

如果您确实只需要存储有限数量的数字,我建议您使用固定精度数据类型。

答案 3 :(得分:3)

我认为这里应该问的问题是: 你为什么需要它被截断?

如果用于比较值,也许你应该考虑使用epsilon测试。 (在你的情况下,有一个额外的公差值,因为它似乎远远大于普遍接受的epsilon)。

如果您只想将其打印为0.6000,请使用其他人建议的方法。

答案 4 :(得分:1)

roundf(myfloat * powf(10, numDigits)) / powf(10, numDigits);

例如,在您的情况下,您将截断三位数(numDigits)。你会用:

roundf(0.6000002 * 1000) / 1000
// And thus:
roundf(600.0002) / 1000
600 / 1000
0.6

(你可能会将powf的结果存储在某个地方,因为你已经使用了两次。)

由于浮动通常存储在计算机上,因此可能存在不准确之处。不过,这就是使用花车的原因。

答案 5 :(得分:1)

使用此:

floor(0.6000002*10000)/10000

答案 6 :(得分:1)

对于C ++ 11,您可以使用标题std::round中定义的<cmath>

auto trunc_value = std::round(value_to_trunc * 10000) / 10000;

答案 7 :(得分:0)

以下是使用其他答案中的建议及其使用示例的函数:

#include <iostream>
#include <cmath>

static void Truncate(double& d, unsigned int numberOfDecimalsToKeep);

int main(int, char*[])
{

  double a = 1.23456789;
  unsigned int numDigits = 3;

  std::cout << a << std::endl;

  Truncate(a,3);

  std::cout << a << std::endl;

  return 0;
}

void Truncate(double& d, unsigned int numberOfDecimalsToKeep)
{
    d = roundf(d * powf(10, numberOfDecimalsToKeep)) / powf(10, numberOfDecimalsToKeep);
}

答案 8 :(得分:0)

与其他答案类似,但你不能忘记圆形,地板和截断是不同的定义。请参阅以下内容的定义和输出示例:

Standard

在这种情况下,我们需要以4位小数的精度进行trucate并去掉非有效小数:

trunc(valueToTrunc*10000)/10000

value = (double)((int)(valueToTrunc*10000))/(double)10000

答案 9 :(得分:0)

您可以使用此:

int n = 1.12378;
cout << fixed << setprecision(4) << n;

输出将为:1.1238

不是:1.1237

最后一个十进制数字不是全部:12.123447 ==> 12.1234

请注意...