我知道有很多关于这个问题的主题,但这些都没有帮助我。我试图通过测试-10到10范围内的每个数字以及两个小数位来找到函数的根。我知道这可能不是最好的方式,但我是初学者,只想尝试一下。不知怎的,循环不起作用,因为我总是得到-10作为输出。 无论如何,那是我的代码:
#include <iostream>
using namespace std;
double calc (double m,double n)
{
double x;
for (x=-10;x<10 && m*x+n==0; x+=0.01)
{
cout << x << endl;
}
return x;
}
int main()
{
double m, n, x;
cout << "......\n";
cin >> m; // gradient
cout << "........\n";
cin >> n; // y-intercept
x=calc(m,n); // using function to calculate
cout << ".......... " << x<< endl; //output solution
cout << "..............\n"; // Nothing of importance
return 0;
}
答案 0 :(得分:5)
您正在循环条件中测试两个条件的结合。
for (x=-10;x<10 && m*x+n==0; x+=0.01
对于许多输入,第二个条件不会为真,因此循环将在第一次迭代之前终止,从而导致返回值为-10
。
你想要的东西可能更接近于以下内容。出于两个原因,我们需要测试绝对值是否小于某个EPSILON
。一,double
不准确。第二,你正在做一个近似的解决方案,所以除非你碰巧幸运,否则你不会指望一个确切的答案。
#define EPSILON 1E-2
double calc (double m,double n)
{
double x;
for (x=-10;x<10; x+=0.001)
{
if (abs(m*x+n) < EPSILON) return x;
}
// return a value outside the range to indicate that we failed to find a
// solution within range.
return -20;
}
更新:根据OP的要求,我将更具体地解决EPSILON
解决的问题。
double
不准确。在计算机中,浮点数通常由固定数量的位表示,位表示通常由诸如IEE 754的标准指定。由于位数是固定且有限的,因此不能表示任意精度数。让我们考虑基础10中的一个示例,以便于理解,尽管您应该了解计算机在基础2中遇到类似的问题。
如果m = 1/3
,x = 3
和n = -1
,我们会期望m*x + n == 0
。但是,由于1/3
是重复的小数0.33333...
,我们只能表示固定数量的3*0.33333
,0.999999
的结果实际上是1
,它不等于{ {1}}。因此,m*x + n != 0
,我们的检查将失败。因此,我们必须通过将其绝对值与我们称为EPSILON
的小数字进行比较来检查结果是否足够接近零,而不是检查零等式。正如其中一条评论指出,EPSILON
对于此特定用途的正确值为std::numeric_limits::epsilon
,但第二个问题需要更大的EPSILON
。
无论如何,你只是在做一个近似的解决方案。由于您以有限的小增量检查x
的值,因此很有可能您只是跨过根而不会完全降落在它上面。考虑等式10000x + 1 = 0
。正确的解决方案是-0.0001
,但如果您采取0.001
的步骤,则永远不会尝试使用值x = -0.0001
,因此您无法找到正确的解决方案。对于线性函数,我们希望x
接近-0.0001
的值(例如x = 0
)会使我们合理地接近正确的解,因此我们使用EPSILON
作为一个软糖因素来解决我们方法中缺乏精确性的问题。
答案 1 :(得分:-1)
m*x+n==0
条件返回false
,因此循环不会启动。
您应该将其更改为m*x+n!=0