浮点算术的最佳实践

时间:2014-07-09 23:50:24

标签: c++ c floating-point int double

我在小数点输入上执行加法和减法,精确到小数点后第二位。我试图通过乘以100将它们转换为整数来提高准确度,但却达到了相反的效果。

考虑以下代码和输出:

double d = 2.01;
int a = (int) (d * 100.0);
cout << a << endl;

输出结果为:

200

一劳永逸,关于浮点算术的一些最佳实践是什么?首先使用上面代码的某个变体将double转换为int,然后将其转换回来,是否可行?

4 个答案:

答案 0 :(得分:6)

如果您将d*100.0的结果打印到(比方说)20位小数,问题将很快显现:

200.99999999999997

由于那个(非常精细)小于201,所以当你转向int时,它会被截断为200。

明显的治疗方法是强行进行四舍五入。至少如果你的输入都是正数,就像在结果中加0.5一样简单:

int a = (int)(d*100.0 + 0.5);

如果你可以指望你的编译器支持它,那么使用标准库round就更容易了:

long a = lround(d*100.0);

这对正数和负数都有效。

答案 1 :(得分:3)

使用标准数学库的舍入函数。在C ++中,这意味着您必须#include <cmath>并使用-lm进行编译。

然后,为您的例子:

double d = 2.01;
long x = lround(d*100);
cout << x << endl; // prints 201, for sure.

这与&#34;添加.5&#34;相同。技巧,但它对正数和负数都能正常工作。

答案 2 :(得分:2)

阅读本文并达成启示:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

  

浮点运算被很多人认为是一个深奥的主题。这是相当令人惊讶的,因为浮点在计算机系统中无处不在。几乎每种语言都有浮点数据类型;从PC到超级计算机的计算机都有浮点加速器;大多数编译器都会被要求不时编译浮点算法;几乎每个操作系统都必须响应溢出等浮点异常。本文提供了一个关于浮点的方面的教程,这些方面对计算机系统的设计者有直接影响。它首先介绍浮点表示和舍入误差,继续讨论IEEE浮点标准,最后总结了许多计算机构建器如何更好地支持浮点数的例子。

答案 3 :(得分:0)

为了得到明确的路由,我会使用floor()和ceil()。

因此,对于以下代码,

 (int)floor( 2.01*100.)

我明白了:

200

但是:

(int)ceil(2.01*100.)

我明白了:

201