当我在c ++中使用fmod(0.6,0.2)时,它返回0.2
我知道这是由浮点精度引起的,但似乎我现在必须得到两倍的余数
非常感谢任何解决此类问题的方法
答案 0 :(得分:2)
数学值0.6
和0.2
无法在二进制浮点中精确表示。
此演示程序将向您显示正在进行的操作:
#include <iostream>
#include <iomanip>
#include <cmath>
int main() {
const double x = 0.6;
const double y = 0.2;
std::cout << std::setprecision(60)
<< "x = " << x << "\n"
<< "y = " << y << "\n"
<< "fmod(x, y) = " << fmod(x, y) << "\n";
}
我的系统(很可能是你的系统)的输出是:
x = 0.59999999999999997779553950749686919152736663818359375
y = 0.200000000000000011102230246251565404236316680908203125
fmod(x, y) = 0.1999999999999999555910790149937383830547332763671875
fmod()
返回的结果在您传递的参数的基础上是正确的。
如果你需要其他一些结果(我认为你期待0.0
),你将不得不做一些不同的事情。有很多种可能性。您可以检查结果是否与0.2
的差异非常小,或者您可以使用整数运算进行计算(例如,如果您处理的所有数字都是{{的倍数] 1}}或0.1
)。
答案 1 :(得分:1)
我认为你最好的选择是使用余数函数而不是fmod。对于给定的示例,它将返回非常小的数字而不是0.2。您可以使用此事实通过舍入到某个精度级别来假设0的余数。
答案 2 :(得分:0)
你是对的,问题是舍入错误。试试这段代码:
#include <stdio.h>
#include <math.h>
int main()
{
double d6 = 0.6;
double d2 = 0.2;
double d = fmod (d6, d2);
printf ("%30.20e %30.20e %30.20e\n", d6, d2, d);
}
当我在gcc 4.4.7中运行它时输出为:
5.99999999999999977796e-01 2.00000000000000011102e-01 1.99999999999999955591e-01
关于如何修复&#34;它,我不知道你究竟要做什么来知道建议什么。总会有一些数字无法用浮点精确表示,所以这种行为是不可避免的。
有关问题域的更多信息有助于获得更好的建议。例如,如果您使用的数字总是只有小数点后的一位数,并且足够小,只需乘以10,舍入到最接近的整数(或长或长),并使用%运算符而不是fmod功能。如果您试图查看fmod的结果是否为0.0,只需接受接近0.2的结果(在这种情况下),就好像接近0一样。