我的代码出了什么问题?它转换英寸和英尺,并以米为单位进行比较。如果我输入12英寸和1英尺,它表示数字不相等。这是g ++的已知问题吗?有人可以向我解释一下吗?
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double in, ft, m1, m2;
cin >> in >> ft;
m1 = in * 0.0254;
m2 = ft * 0.3048;
cout << m1 << '\t' << m2 << '\n' << endl;
// to show that both numbers are equal
if (m1 == m2) cout << "yay";
else cout << "boo";
}
还有其他人有这个问题吗?
答案 0 :(得分:0)
您所看到的是不精确浮点表示的结果。基数2 ^ n浮点数不能完全代表所有基数10的十进制值。因此,当你做一些简单的事情,比如乘以12 * 0.0254,就会得到0.3047999 ....... 6的非常奇怪的结果,而如果你计算1 * 0.3048,你会得到0.3048的预期结果。问题是0.0254没有准确存储;相反,使用最接近的近似值(类似于0.0253999999 .... 98)。差异很小,但在计算中使用不精确值时会变得明显,然后将其与另一个不会出现舍入问题的值(例如0.3048)进行比较。要记住的基本规则是,永远比较浮点值是否相等;相反,以允许可接受的错误的方式比较它们,例如,而不是按以下方式比较值:
if(val1 == val2)...
使用类似
的内容if(abs(val1 - val2) < 0.0000001)...
如果它们的值相差小于1 / 10,000,000(这非常接近: - ),则两个变量将被视为相等。
答案 1 :(得分:0)
数字不匹配的原因是计算机使用数字的二进制表示,这在尝试表示十进制数时会导致不准确。
您认为该数字为0.3048(因为这是您编码的内容) - 但在编译时,计算机只能将其表示为二进制格式中最接近的等效项(有关详细信息,请参阅IEEE floating point)。所以数字可能非常接近0.3048,但不是那么精确。
完成计算后,你会比较数字 - 但如果两者在二进制表示中不完全相同,则它们将不匹配。
解决它的一种简单方法(但绝不是唯一的解决方案)它可以减去两个操作数并检查它是多么接近于零。如果:
fabs(a-b)&lt; 0.00001
(任意数量),那么你可以设定值是相同的。
答案 2 :(得分:0)
@Josh,将其添加到您的代码并运行它
cout << m2-m1;
你会感到惊讶,回答不是零
对于代码中的问题,将数据类型从double更改为float可以解决问题
float in, ft, m1, m2;