Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 浮点运算的最佳实践_C++_C_Floating Point_Int_Double - Fatal编程技术网

C++ 浮点运算的最佳实践

C++ 浮点运算的最佳实践,c++,c,floating-point,int,double,C++,C,Floating Point,Int,Double,我正在对精确到小数点后第二位的小数进行加减运算。我试图通过将它们乘以100来转换为整数来提高精度,但结果适得其反 考虑以下代码和输出: double d = 2.01; int a = (int) (d * 100.0); cout << a << endl; 一劳永逸地说,关于浮点算术的一些最佳实践是什么?首先使用上述代码的某种变体将double转换为int,然后再将其转换回是否可行?如果将d*100.0的结果打印到(比如)20位小数,问题很快就会变得明显: 200.

我正在对精确到小数点后第二位的小数进行加减运算。我试图通过将它们乘以100来转换为整数来提高精度,但结果适得其反

考虑以下代码和输出:

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

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

如果将
d*100.0
的结果打印到(比如)20位小数,问题很快就会变得明显:

200.99999999999997
因为它(非常小)小于201,所以当您转换为
int
时,它会被截断为200

显而易见的解决办法是强制倒圆。至少如果您的输入都是正数,那么只需将结果加上0.5即可:

int a = (int)(d*100.0 + 0.5);
如果您可以指望编译器支持它,那么使用标准库的
循环

long a = lround(d*100.0);

这适用于正数和负数。

阅读此内容并获得启示:

浮点运算被许多人认为是一门深奥的学科。这相当令人惊讶,因为浮点运算在计算机系统中无处不在。几乎每种语言都有浮点数据类型;从个人电脑到超级计算机都有浮点加速器;大多数编译器会不时被要求编译浮点算法;实际上,每个操作系统都必须响应浮点异常,例如溢出。本文介绍了一个有关浮点运算的教程,这些方面对计算机系统的设计者有着直接的影响。它从浮点表示和舍入误差的背景开始,继续讨论IEEE浮点标准,并以计算机构建者如何更好地支持浮点的众多示例结束


为了得到定义良好的胭脂,我将使用floor()和ceil()

因此,对于以下代码

 (int)floor( 2.01*100.)
我得到:

200
但对于:

(int)ceil(2.01*100.)
我得到:

201

使用标准数学库的舍入函数。在C++中,这意味着你必须使用< <代码> > >编译< <代码> > LM 然后,以你为例:

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

cout
(int)(d*100.0+0.5)
?解决方案:不要对货币使用浮点。如果您只有两位小数(这是货币吗?)。在任何地方都使用整数,并且在显示它时正确地格式化它。只要停止假设一个微便士对会计师很重要,你就不会有什么实际问题。把那一小便士提高到一便士肯定会给你带来麻烦。正如您所发现的那样,@lwxted与其说100是特殊的,不如说它是2.01,它比201更接近二的幂。你可以很容易地得到201层和202层;这种方法没有任何区别上次我提出这个解决方案时,有人抱怨说,如果2^52rint()
函数。@tmyklebu,
rint
返回一个浮点值,因此不能解决OP的问题<代码>打印
用于将3.2更改为3.0,而不是将3.0转换为3.0。(正确的用法是
lrund
,如我下面的回答所示。)本文介绍了一个有关浮点运算的教程,这些方面对计算机系统的设计者有直接影响。确切地说,这不是一篇针对浮点数和算术的普通用户的论文。Wikipedia文章()对于大多数程序员来说是一个更好的起点,对他们中的许多人来说,它提供了他们需要知道的一切。我真希望人们不要再向任何在这里提出关于浮点运算的初级问题的人本能地推荐Goldberg的论文了。@HighPerformanceMark:但当你引用它时,它会让你看起来很开明!作为奖励,当你在两次评论后说了一些不可言喻的愚蠢话时,每个人都会认为你在讲福音。
double d = 2.01;
long x = lround(d*100);
cout << x << endl; // prints 201, for sure.