Java:实现简单的等式

时间:2009-11-29 12:32:23

标签: java equations

我希望实现简单的等式:

  

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才能使它们正确(我想要获得正确值的数字)。

如果可能的话,我想找到一种更好的方法来执行上面的等式,因为我的做法似乎是错误的,只是有效。我希望按照等式所暗示的方式来做,而不是破解它的工作。

5 个答案:

答案 0 :(得分:6)

quadratic equation通常用abc表示。为了满足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节提出了一种更好的方法:如果我们定义

alt text
(来源:equationsheet.com

然后两个根是:

alt text

alt text

您的代码还需要考虑病态情况(例如,a = 0)。

让我们用你的价值观代替这些公式,看看我们得到了什么。如果a = 10,b = 7,c = 10,那么:

alt text
(来源:equationsheet.com

然后两个根是:

alt text
(来源:equationsheet.com

alt text
(来源:equationsheet.com

我认为我有正确的迹象。

如果您的计算给您带来麻烦,可能是因为您的方法无法正确考虑您的复杂根源。你需要一个复杂的数字类。