int Solve(double& root1,double& root2) //this is function in the class Eq2
{
int discrimant = b*b - 4*a*c;
if(discriminant<0)
return false;
else if(discriminant>0)
{
root1 = (-b - sqrt(discriminant))/(2*a);
root2 = (-b + sqrt(discriminant))/(2*a);
return root1; //must return root1 and root2
}
}
int main()
{
Eq2 eq1(1, -5, 6); //discriminant=1,root1=2,root2=3
Eq2 eq2(1, -6, 8); //discriminant=4,root1=2,root2=4
Eq2 eq3(1, 2, 3);
Eq2 eq4(0, 0, 0);
double root1, root2;
Eq2 eqq[4] = { eq1,eq2,eq3,eq4 };
for (int i = 0; i < 4; i++)
{
eqq[i].print();
}
cout << "The roots of the equation are:"<<eq1.Solve(root1,root2); //here
i call the function
system("pause");
return 0;
}
我使函数int起作用了,但是我只能输出1个root。我需要返回root1和root2。谢谢大家的帮助!我仍处于起步阶段,我还有很多东西要学习。
答案 0 :(得分:4)
免责声明:
在编写我自己的MCVE时,OP编辑了问题。因此,我的标识符有些不同。我希望这不会引起混乱...
Discriminant是一个非常特殊的词,我立刻想起了我在数学中学到的。其余的丢失了,但立即从Wikipedia和google找到的其他内容中刷新了。
OP的实际问题似乎在于了解如何使用reference parameters来从函数中返回值而不使用(或不使用)return
。恕我直言,其他答案已经对此进行了介绍。
因此,我专注于演示这一点。
因此,我注意到了一些应考虑的其他问题。
std::sqrt
仅应以值≥0调用。如果参数小于-0,则引发FE_INVALID并返回NaN。
应检查除以0。
(由于我的同事Dipl.-Math的暗示。)由于值很小,所以除法的结果变得不可信任。
由于通常的舍入问题,将浮点值与常量进行比较通常是一个坏主意。因此,我介绍了eps
–一点点补偿的epsilon值。
示例代码:
#include <cmath>
#include <iostream>
struct Quad {
double a, b, c;
Quad(double a, double b, double c): a(a), b(b), c(c) { }
Quad(const Quad&) = default;
Quad& operator=(const Quad&) = default;
~Quad() = default;
bool solve(double &root1, double &root2) const;
};
std::ostream& operator<<(std::ostream &out, const Quad &quad)
{
return out << quad.a << "x² + " << quad.b << "x + " << quad.c;
}
static double eps = 1E-10;
/* tries to solve the roots of this quadratic function.
*
* return: true (solution exists)
* root1 and root2 contain results
* false (no solution)
* root1 and root2 are indeterminate (unchanged)
*/
bool Quad::solve(double &root1, double &root2) const
{
double discriminant = b * b - 4 * a * c;
if (discriminant < 0.0) return false; // square root of a negative!
if (std::abs(a) < eps) return false; // division by 0! (or close to 0)
root1 = (-b - std::sqrt(discriminant)) / (2 * a);
root2 = (-b + std::sqrt(discriminant)) / (2 * a);
return true;
}
int main()
{
double root1, root2; // declared but not yet initialized
Quad quad1(-1, 0, 1); // two solutions
std::cout << "Roots for " << quad1 << ": ";
if (!quad1.solve(root1, root2)) std::cout << "none\n";
else std::cout << root1 << ", " << root2 << '\n';
Quad quad2(1, -4, 4); // one solution
std::cout << "Roots for " << quad2 << ": ";
if (!quad2.solve(root1, root2)) std::cout << "none\n";
else std::cout << root1 << ", " << root2 << '\n';
Quad quad3(1, 0, 2); // no solution
std::cout << "Roots for " << quad3 << ": ";
if (!quad3.solve(root1, root2)) std::cout << "none\n";
else std::cout << root1 << ", " << root2 << '\n';
}
输出:
Roots for -1x² + 0x + 1: 1, -1
Roots for 1x² + -4x + 4: 2, 2
Roots for 1x² + 0x + 2: none
诀窍在于,Quad::solve()
返回true
或false
(如所记录),并在前一种情况下更新变量root1
和root2
,但不更新后者。
以不太紧凑的形式编写:
bool valid = quad1.solve(root1, root2);
if (valid) { // root1, root2 updated
std::cout << root1 << ", " << root2 << '\n';
} else { // no result computed -> root1, root2 not updated
std::cout << "none\n";
}
我从这个German site中提取了样本值。
答案 1 :(得分:2)
对于返回类型应该是什么存在一些争论,我认为int
比bool
更好,因为您可能要发出三种不同的返回方案(无根,单根和两个根)。您可以辩称,可以通过在调用方中进行root1 == root2
比较来区分后两者,但是如果必须返回成功值,为什么不让它能够表达所有选项。
所以我的答案应该是这样的:
int Solve(double& root1, double& root2)
{
int discriminant = b * b - 4 * a * c;
if (discriminant < 0) // No roots
return 0;
if (discriminant == 0) // One root
{
root1 = (-b) / (2 * a);
root2 = root1;
return 1;
}
// Two roots
root1 = (-b - sqrt(discriminant)) / (2 * a);
root2 = (-b + sqrt(discriminant)) / (2 * a);
return 2;
}
int main()
{
Eq2 eq1(1, -5, 6); //discriminant=1,root1=2,root2=3
Eq2 eq2(1, -6, 8); //discriminant=4,root1=2,root2=4
Eq2 eq3(1, 2, 3);
Eq2 eq4(0, 0, 0);
double root1, root2;
Eq2 eqq[4] = { eq1,eq2,eq3,eq4 };
for (int i = 0; i < 4; i++)
{
eqq[i].print();
}
int numRoots = eq1.Solve(root1, root2);
switch (numRoots) {
case 0:
cout << "The the equation has no roots" << endl;
break;
case 1:
cout << "The the equation has one root: " << root1 << endl;
break;
case 2:
cout << "The the equation has two roots: " << root1 << ", " << root2 << endl;
break;
default:
cout << "Error: This should be impossible" << endl;
break;
}
system("pause");
return 0;
}
答案 2 :(得分:1)
如注释中所建议:在这种情况下,“返回”是一个不明确的术语。您希望调用者能够获得第二级方程的根。
由于root1和root2是通过引用传递的,因此只需分配它们的值即可为调用者提供正确的值。您应该返回的是正确的。并且您应该检查判别式是否小于0并在这种情况下返回false。
如@Marichyasana所建议,可能所有int
都应成为double
。
bool Solve(double& root1, double& root2)
{
int discrimant = b*b - 4*a*c;
if (discriminant < 0)
return false;
root1 = (-b - sqrt(discriminant))/(2*a);
root2 = (-b + sqrt(discriminant))/(2*a);
return true;
}
答案 3 :(得分:1)
我将在一个答案中总结评论中的所有建议:
double
代替int
,因为sqrt
函数返回double
false
,否则可以返回true
答案 4 :(得分:0)
签名很奇怪,返回根目录似乎更合适:
std::vector<double> SolveEq2(double a, double b, double c)
{
if (a == 0) {
throw std::runtime_error("Not equation of 2nd degree");
}
auto discriminant = b*b - 4*a*c;
if (discriminant < 0) {
return {}; // No roots;
}
else if (discriminant > 0)
{
auto sqrtDiscriminant = sqrt(discriminant);
return {(-b - sqrtDiscriminant) / (2 * a),
(-b + sqrtDiscriminant) / (2 * a)};
} else { // == 0
return {-b / (2 * a)};
}
}