我在小数点输入上执行加法和减法,精确到小数点后第二位。我试图通过乘以100将它们转换为整数来提高准确度,但却达到了相反的效果。
考虑以下代码和输出:
double d = 2.01;
int a = (int) (d * 100.0);
cout << a << endl;
输出结果为:
200
一劳永逸,关于浮点算术的一些最佳实践是什么?首先使用上面代码的某个变体将double
转换为int
,然后将其转换回来,是否可行?
答案 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