Fmod函数显然输出一个预期的double,但是if(fmod == expected double)不能评估为true [duplicate]

问题描述 投票:2回答:1

这个问题在这里已有答案:

当我调用我的函数时:

formatCurrency(7.5);

string formatCurrency(double cash) {
cout << "fmod(cash,.1) is equal to " << fmod(cash,.1) << endl;
if(fmod(cash,1) == 0) {
    cout << cash << ".00";
}
else if(fmod(cash,.1) == 0.1) {
    cout << cash << "0";
}
else if(fmod(cash,.01) == 0.01) {
    cout << cash;
}
else{
    cout << "Error: unable to display in currency format";
}
return "";
}

fmod(7.5,.1)显然等于.1,当我运行程序时它甚至会输出。但我得到以下输出:

fmod(cash,.1) is equal to 0.1
Error: unable to display in currency format

是什么赋予了?我觉得我的代码没有任何问题。代码可以使用整数/第一个if语句,但任何带小数的东西都会让事情变得有点冒险。

c++ floating-point comparison
1个回答
2
投票

浮点数据类型是有限的并且具有不精确性。它们的编码方式使初学者对于哪些值不精确而言非常不直观(例如0.5将被精确表示,0.1需要舍入)。

有关于IEEE浮点编码的详细介绍的书籍,但对于初学者来说,任何维基百科的文章都是一个很好的开始感受它:https://en.wikipedia.org/wiki/Floating-point_arithmetic

此问题有不同的解决方案,具体取决于您的域名,例如:使用像MPFR(https://www.mpfr.org/)这样的任意精度库。大多数单元测试框架都决定不使用==相等,而是引入“足够接近”的比较。例如,JUnit的assertEquals用于double有效地检查以下内容:

Math.abs(d1 - d2) <= some_small_delta

另见:JUnit assertEquals(double expected, double actual, double epsilon)

因此,如果两个数字之间的差异足够小,则认为它们是相等的。在货币的背景下,一个常见的选择是决定你的系统需要的最小面额(例如,当货币是“美元”时可能是“美分”)并且总是将“1美元”表示为具有值int而不是a的100。值为1.0的浮点数。甚至还有库来简化这项任务,有效地建模定点数据类型。

也可以看看:

© www.soinside.com 2019 - 2024. All rights reserved.