使用双精度的程序的意外行为
Unexpected behaviour of a program using doubles
可能的重复:
为什么Visual Studio 2008告诉我.9 - .8999999999999995 = 0.0000000000000000055511151231257827?
为什么像 1.82 这样的简单双精度最终会变成 1.8199999999645634565360?
当我编译和运行以下程序时,我得到了一个非常奇怪的行为:
#include <iostream>
#define DIV 10000ll
long long gcd(long long a, long long b) {
if(b==0) return a;
else return gcd(b, a % b);
}
int main() {
int t;
std::cin >> t;
while(t--) {
double n1;
std::cin >> n1;
long long inum=(long long)(n1*DIV);
std::cout << inum << std::endl;
if(inum==0) { std::cout << 1 << std::endl; }
else std::cout << DIV/gcd(inum,DIV) << std::endl;
}
return 0;
}
当我输入时:
1
0.0006
我得到作为输出
5
2000
这意味着:(long long)0.0006*10000
等于 5 而不是 6。为什么会这样?
> 0.0006 不能完全表示为双精度。存储的实际结果很可能是 0.00059999999...当此值乘以 10000 时,它给出的数字略小于 6。将其转换为整数类型会将其截断(向下舍入)为 5。
这不是奇怪的行为。这就是浮点运算的工作原理。如果要获取值 6,则应舍入到最接近的整数,而不是截断。
相关
- round() 表示 C++ 中的浮点数
我的猜测是它与浮点精度有关。 .0006 在计算机中可能类似于 .0005999999999,然后将其乘以 10,000,然后将其转换为长整型,从而删除小数,因此 5.999999 变为 5。
尝试使用long double
改用,这是一个浮点精度错误,修复它的简单方法是使用更精确的浮点类型。 除非是截断错误,在这种情况下,您需要在投射之前进行舍入。
相关文章:
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 多线程程序中出现意外的内存泄漏
- C++ 程序意外退出
- 在gcc中意外调用了Const重载.编译器错误或兼容性修复程序
- 如果我删除指针,我的C++程序会意外删除系统文件吗?
- Qt 应用程序具有意外的 QDir::currentPath
- 排序程序的意外错误代码
- 以下程序的意外输出
- QT应用程序意外的语言事件
- 简单程序中的意外推力错误
- 程序意外终止C
- 设置终止和意外处理程序
- 双精度数字程序意外值
- QWT示例该程序已经意外完成
- 使用双精度的程序的意外行为
- 查找素数的程序意外停止
- 程序意外地完成了-QT创建者
- cpp 程序中的意外输出
- 当我在递归函数中调用 return 时,我的程序意外完成
- Arduino上的意外程序停止