Java:实现简单的方程

发布于 2024-08-13 06:04:15 字数 623 浏览 4 评论 0原文

我正在寻找实现这个简单的方程:

i,j = -Q ± √(Q2-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

:简单地说,test 取方程的第一部分并将其修改为 0 到 11 之间的非零整数,然后写入 i 和 j。 i 和 j 返回正确的数字,但由于某种原因需要 *-10 才能使它们正确(我猜想获得正确值的数字)。

如果可能的话,我想找到一种更好的方法来执行上述方程,因为我的方法似乎是错误的,但只是有效。我想按照等式的建议去做,而不是破解它来工作。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月棠 2024-08-20 06:04:15

二次方程通常用a、<代码>b和c。为了满足 ax2+bx+c = 0,您将得到 (-b +/- sqrt(b^2-4ac)) / 2a 作为答案。

我认为你的基本问题是你出于某种原因使用而不是取平方根。 -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);
}

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);
}
刘备忘录 2024-08-20 06:04:15

您需要求平方根。请注意,Q^2-4PR 产生负数,因此您将必须处理复数(或限制输入以避免这种情况)。 Apache Math 可能会对您有所帮助。

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.

请别遗忘我 2024-08-20 06:04:15

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

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;
}
夏有森光若流苏 2024-08-20 06:04:15

为什么你做模而不是平方根?您的代码似乎是获得二次方程根的方法 ((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)

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)
最冷一天 2024-08-20 06:04:15

正如其他人所指出的,您对 mod 的使用甚至没有错误。你为什么要这样编数学?

众所周知,如果 b 的值非常接近判别式,则二次方程的朴素解可能会出现问题。

“C++ 中的数值配方”的第 5.6 节建议了更好的方法:如果我们定义

替代文本
(来源:equationsheet.com

然后两个根是:

“替代文本”

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

让我们将您的值代入这些公式,看看会得到什么。如果 a = 10、b = 7、c = 10,则:

alt 文本
(来源:equationsheet.com

两个根是:

替代文字
(来源:equationsheet.com

< a href="https://i.sstatic.net/2tchE.gif" rel="nofollow noreferrer">替代文本
(来源:equationsheet.com

我认为我有正确的迹象。

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

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

alt text
(source: equationsheet.com)

Then the two roots are:

alt text

and

alt text

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 :

alt text
(source: equationsheet.com)

Then the two roots are:

alt text
(source: equationsheet.com)

and

alt text
(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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文