Ani*_*ian 3 c++ floating-point rounding
可能重复:
为什么不对双精度值的操作给出预期结果?
我在C++中遇到了一个特殊的问题.我创建了一个Double类型的变量.然后我做了一些计算,将一些值分配给其他变量,并将结果分配给我声明的双变量.它给了我一个长小数部分的结果.我希望它只舍入到小数点后2位.并将其存储到变量中.但即使在几次尝试四舍五入之后,我也无法将其舍入到小数点后两位.
然后我尝试了另一种方法来检查真正的问题是什么.我创建了一个Double变量并为其赋值1.11.但是当我通过设置断点并为该变量添加监视来调试它时,我发现现在存储在变量中的值是1.109999999999.
我的问题是,为什么会这样显示?我们有什么方法可以将变量舍入到两位小数?为什么即使我们分配一个只有两位小数的数字,它也显示一个长小数部分?
请建议一种方法来存储数字 - 无论是计算数字还是直接分配数字 - 实际上是双变量而不是带小数字长的数字.
fre*_*low 11
在double值的集合中,没有数字1.11,因为在内部,double使用二进制表示(与用于十进制表示的人相对).大多数有限十进制数(例如1.11)在二进制中具有无限表示,但由于内存有限,因为四舍五入会导致精度损失.
使用双数据类型最接近1.11的是1.1100000000000000976996261670137755572795867919921875,其内部表示为0x3ff1c28f5c28f5c3.
您对小数点后两位的要求听起来像是在用钱.一个简单的解决方案是将美分存储在一个整数中(而不是双重中的美元):
int cents = 111;
Run Code Online (Sandbox Code Playgroud)
这样,你就不会失去任何精确度.另一种解决方案是使用专用的十进制数据类型.
像 float 和 double 这样的浮点类型不是 100% 精确的。他们可能会将 14.3 存储为 14.299999 ......这并没有错。这就是为什么你不应该用 == 运算符比较两个浮点数或双精度数,instread 你应该检查它们差异的绝对值是否小于某个 epsilon,比如 0.000000001
现在,如果你想以一种愉快的方式输出数字,你可以使用setprecisionfrom<iomanip>
例如
#include <iostream>
#include <iomanip>
int main()
{
double d = 1.389040598345;
std::cout << setprecision(2) << d; //outputs 1.39
}
Run Code Online (Sandbox Code Playgroud)
如果你想得到点后保留2位小数的d的值,那么你可以使用这个公式
d = floor((d*100)+0.5)/100.0; //d is now 1.39
Run Code Online (Sandbox Code Playgroud)