g++ 中的比较函数

comparison function in g++

我的代码有什么问题?它转换英寸和英尺并以米为单位进行比较。如果我为英寸输入 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";
}

还有其他人有这个问题吗?

您看到的是不精确浮点表示的结果。以 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(非常接近 :-),则它们将被视为相等。

数字不匹配的原因是计算机使用二进制表示数字,这会导致在尝试表示十进制数字时不准确。

您认为该数字是 0.3048(因为这是您编码的内容)- 但在编译时,计算机只能将其表示为二进制格式中最接近的等效值(有关详细信息,请参阅 IEEE floating point)。所以这个数字可能非常接近 0.3048,但不完全是。

完成计算后,比较数字 - 但如果两者的二进制表示形式不完全相同,则它们不会匹配。

解决它的一个简单方法(但绝不是唯一的解决方案)是减去两个操作数并检查它与零的接近程度。如果:

fabs(a - b) < 0.00001

(任意数量),那么你可以假设值是相同的。

@Josh,将其添加到您的代码中并 运行 它

cout << m2-m1; 

你会很惊讶,答案不是零

对于代码中的问题,将数据类型从 double 更改为 float 可以解决问题

float in, ft, m1, m2;