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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fmod函数显然输出一个预期的double,但是if(fmod == expected double)不能评估为true [duplicate]相关的知识,希望对你有一定的参考价值。

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

当我调用我的函数时:

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语句,但任何带小数的东西都会让事情变得有点冒险。

答案

浮点数据类型是有限的并且具有不精确性。它们的编码方式使初学者对于哪些值不精确而言非常不直观(例如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的浮点数。甚至还有库来简化这项任务,有效地建模定点数据类型。

也可以看看:

以上是关于Fmod函数显然输出一个预期的double,但是if(fmod == expected double)不能评估为true [duplicate]的主要内容,如果未能解决你的问题,请参考以下文章

fmod()函数 (对浮点数取模)

使用 cmath 的 fmod (C++) 时的不一致

iOS的match函数

不能在 iOS 上包含 FMOD

在 Opencv 中将数据放入 Mat 对象中

c语言打印double类型