我希望实现简单的等式:
i,j = -Q±√(Q 2 -4PR)/ 2P
为此,我有以下代码(注意:P = 10. Q = 7. R = 10):
//Q*Q – 4PR = -351 mod 11 = -10 mod 11 = 1, √1 = 1
double test = Math.sqrt(modulo(((Q*Q) - ((4*P)*R))));
// Works, but why *-10 needed?
i = (int)(((-Q+test)/(P*2))*-10); // i = 3
j = (int)(((-Q-test)/(P*2))*-10); // j = 4
简单地说,测试采用等式的第一部分并将其修改为介于0和11之间的非零整数,然后写入i和j。 i和j返回正确的数字,但由于某种原因需要* -10才能使它们正确(我想要获得正确值的数字)。
如果可能的话,我想找到一种更好的方法来执行上面的等式,因为我的做法似乎是错误的,只是有效。我希望按照等式所暗示的方式来做,而不是破解它的工作。
答案 0 :(得分:6)
quadratic equation通常用a
,b
和c
表示。为了满足ax 2 + bx + c = 0,你得到(-b +/- sqrt(b^2-4ac))
/ 2a作为答案。
我认为您的基本问题是您出于某种原因使用 modulo 而不是取平方根。因子-10只是一个软件因素,恰好适用于您的测试用例。
你应该有这样的东西:
public static void findRoots(double a, double b, double c)
{
if (b * b < 4 * a * c)
{
throw new IllegalArgumentException("Equation has no roots");
}
double tmp = Math.sqrt(b * b - 4 * a * c);
double firstRoot = (-b + tmp) / (2 * a);
double secondRoot = (-b - tmp) / (2 * a);
System.out.println("Roots: " + firstRoot + ", " + secondRoot);
}
编辑:您的modulo
方法目前正在慢慢递归。试试这个:
public static int modulo(int x)
{
return ((x % 11) + 11) % 11;
}
基本上第一个% 11
的结果将在[-10,10]的范围内 - 所以在添加另一个11并再次使用% 11
之后,它会是对的。无需递归。
此时没有太多理由将其作为单独的方法,因此您可以使用:
public static void findRoots(double a, double b, double c)
{
int squareMod11 = (((b * b - 4 * a * c) % 11) + 11) % 11;
double tmp = Math.sqrt(squareMod11);
double firstRoot = (-b + tmp) / (2 * a);
double secondRoot = (-b - tmp) / (2 * a);
System.out.println("Roots: " + firstRoot + ", " + secondRoot);
}
答案 1 :(得分:1)
你需要取平方根。请注意,Q ^ 2-4PR会产生一个负数,因此您将不得不处理复数(或限制输入以避免这种情况)。 Apache Math可能会对您有所帮助。
答案 2 :(得分:1)
使用Math.sqrt作为平方根。为什么要将i和j投射到整数?它是给出方形函数根的等式,因此i和j可以是任何复数。您应将判别式限制为实数(双)根的正值,否则使用复数。
double test = Q*Q - 4*P*R;
if(Q < 0) throw new Exception("negative discriminant!");
else {
test = Math.sqrt(test);
double i = (-Q + test) / 2*P;
double i = (-Q - test) / 2*P;
}
答案 3 :(得分:0)
你为什么要做模数而不是平方根?你的代码似乎是获得二次方程的根的方法((a±sqrt(b ^ 2-4ac))/ 2a),所以代码应该是:
double delta = Q*Q-4*P*R);
if(delta < 0.0) {
throw new Exception("no roots");
}
double d = Math.power(delta,0.5);
double r1 = (Q + d)/(2*P)
double r2 = (Q - d)/(2*P)
答案 4 :(得分:0)
正如其他人所指出的,你对mod的使用甚至都没有错。你为什么要编写这样的数学?
众所周知,如果b的值非常接近判别式,那么二次方程的朴素解可能会出现问题。
“C ++中的数字食谱”第5.6节提出了一种更好的方法:如果我们定义
(来源:equationsheet.com)
然后两个根是:
和
您的代码还需要考虑病态情况(例如,a = 0)。
让我们用你的价值观代替这些公式,看看我们得到了什么。如果a = 10,b = 7,c = 10,那么:
(来源:equationsheet.com)
然后两个根是:
(来源:equationsheet.com)
和
(来源:equationsheet.com)
我认为我有正确的迹象。
如果您的计算给您带来麻烦,可能是因为您的方法无法正确考虑您的复杂根源。你需要一个复杂的数字类。