开发者

Java: Implementing simple equation

I am looking to implement the simple equation:

i,j = -Q ± √(Q2-4PR) / 2P

To do so I have the following code (note: 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

To put it simply, test takes the first part of the equation and mods it to a non-zero integer in-between 0 and 11, then i and j are written. i and j return the right number, but for some reason *-10 is needed to get them right (a number I guessed to get the correct values).

If possible, I'd like to find a better way of performing the above equation because my way of doing it seems wrong and just works.开发者_开发问答 I'd like to do it as the equation suggests, rather than hack it to work.


The quadratic equation is more usually expressed in terms of a, b and c. To satisfy ax2+bx+c = 0, you get (-b +/- sqrt(b^2-4ac)) / 2a as answers.

I think your basic problem is that you're using modulo for some reason instead of taking the square root. The factor of -10 is just a fudge factor which happens to work for your test case.

You should have something like this:

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);
}

EDIT: Your modulo method is currently going to recurse pretty chronically. Try this instead:

public static int modulo(int x)
{
    return ((x % 11) + 11) % 11;
}

Basically the result of the first % 11 will be in the range [-10, 10] - so after adding another 11 and taking % 11 again, it'll be correct. No need to recurse.

At that point there's not much reason to have it as a separate method, so you can use:

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);
}


You need to take the square root. Note that Q^2-4PR yields a negative number, and consequently you're going to have to handle complex numbers (or restrict input to avoid this scenario). Apache Math may help you here.


use Math.sqrt for the square root. Why do you cast i and j to ints? It is equation giving you roots of square function, so i and j can be any complex numbers. You shall limit the discriminant to positive-only values for real (double) roots, otherwise use complex numbers.


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;
}


Why are you doing modulo and not square root? Your code seems to be the way to get the roots of a quadratic equation ((a±sqrt(b^2-4ac))/2a), so the code should be:

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)


As pointed out by others, your use of mod isn't even wrong. Why are you making up mathematics like this?

It's well known that the naive solution to the quadratic equation can have problems if the value of b is very nearly equal to the discriminant.

A better way to do it is suggested in section 5.6 of "Numerical Recipes in C++": if we define

Java: Implementing simple equation


(source: equationsheet.com)

Then the two roots are:

Java: Implementing simple equation

and

Java: Implementing simple equation

Your code also needs to account for pathological cases (e.g., a = 0).

Let's substitute your values into these formulas and see what we get. If a = 10, b = 7, and c = 10, then :

Java: Implementing simple equation


(source: equationsheet.com)

Then the two roots are:

Java: Implementing simple equation


(source: equationsheet.com)

and

Java: Implementing simple equation


(source: equationsheet.com)

I think I have the signs right.

If your calculation is giving you trouble, it's likely due to the fact that you have complex roots that your method can't take into account properly. You'll need a complex number class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜