在Java中求解三次方程式时遇到问题 [英] Having trouble solving cubic equations in Java

查看:75
本文介绍了在Java中求解三次方程式时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试遵循一些伪代码来解决《程序员的数学和物理学》第3章中的立方方程,据我所知,我已经正确地遵循了它,但似乎没有得到正确的输出

I'm attempting to follow some psuedo code for solving cubic equations in Mathematics and Physics for Programmers, Chapter 3, as far as I can see I've followed it accurately, but I don't seem to be getting correct outputs.

例如:根据Wolfram Alpha,5x ^ 3 + 4x ^ 2 + 3x + 2 = 0应该给出x≈-0.72932的根,但是我从脚本中得到-1.8580943294965526.

For example: According to Wolfram Alpha 5x^3 + 4x^2 + 3x + 2 = 0 should give a root of x≈-0.72932, but I'm getting back -1.8580943294965526 from my script.

有人可以帮我弄清楚我在做什么吗?我正在跟踪脚本,以更好地理解数学并将方程式转换为代码.但这只是我的理解的边缘,因此我发现调试起来很麻烦.再加上这本书没有勘误表,并且许多在线评论都指出这本书有很多错误,我正努力查看问题出在我的代码,书籍的说明还是两者有关.

Can someone help me to work out what the hell I'm doing? I'm following the scripts to get a better understanding of maths and converting equations to code. But this is at the brink of my understanding so I'm finding it troublesome to debug. Coupled with the fact the book has no errata and many online reviews state the book has many errors, I'm struggling to see whether the issue is with my code, the books explanation or both.

书中给出的等式是:

然后,如果判别式> 0,则根的值为r + s:

Then if the discriminant > 0 then root has value of r+s:

如果判别式== 0,则有两个根:

if discriminant == 0 then there are two roots:

如果判别< 0,您可以找到三个根,如下所示:

if discriminant < 0 you can find three roots as follows:

找到 t 后,您可以通过以下操作将其转换为 x :

After finding t you can transform it to x by taking:

package com.oacc.maths;

public class SolveCubic {

    public static double[] solveCubic(double a, double b, double c, double d) {
        double[] result;
        if (d != 1) {
            a = a / d;
            b = b / d;
            c = c / d;
        }

        double p = b / 3 - a * a / 9;
        double q = a * a * a / 27 - a * b / 6 + c / 2;
        double D = p * p * p + q * q;

        if (Double.compare(D, 0) >= 0) {
            if (Double.compare(D, 0) == 0) {
                double r = Math.cbrt(-q);
                result = new double[2];
                result[0] = 2 * r;
                result[1] = -r;
            } else {
                double r = Math.cbrt(-q + Math.sqrt(D));
                double s = Math.cbrt(-q - Math.sqrt(D));
                result = new double[1];
                result[0] = r + s;
            }
        } else {
            double ang = Math.acos(-q / Math.sqrt(-p * p * p));
            double r = 2 * Math.sqrt(-p);
            result = new double[3];
            for (int k = -1; k <= 1; k++) {
                double theta = (ang - 2 * Math.PI * k) / 3;
                result[k + 1] = r * Math.cos(theta);
            }

        }
        for (int i = 0; i < result.length; i++) {
            result[i] = result[i] - a / 3;
        }
        return result;
    }


    public static double[] solveCubic(double a, double b, double c) {
        double d = 1;
        return solveCubic(a, b, c, d);
    }

    public static void main(String args[]) {
        double[] result = solveCubic(5, 4, 3, 2);
        for (double aResult : result) {
            System.out.println(aResult);
        }
    }
}

我还在书本网站上找到了此代码示例(nb,这不是书中的伪代码):

I also found this code example from the book site(n.b. this is not the psuedo code from the book): http://www.delmarlearning.com/companions/content/1435457331/files/index.asp?isbn=1435457331

 on solveCubic(a,b,c,d)
 --! ARGUMENTS: 
a, b, c, d (all numbers). d is optional (default is 1)
 --! 
RETURNS: the list of solutions to dx^3+ax^2+bx+c=0


-- if d is defined then divide a, b and c by d 
 if not voidp(d) 
then
 if d=0 then return solveQuadratic(b,c,a)

set d to float(d)
 set a to a/d
 set b to b/d
 set 
c to c/d
 else
 set a to float(a)
 set b to float(b)

 set c to float(c)
 end if

 set p to b/3 - a*a/9

 set q to a*a*a/27 - a*b/6 + c/2
 set disc to p*p*p + q*q


 if abs(disc)<0.001 then 
 set r to cuberoot(-q)
 set ret to [2*r, -r]
 else if disc>0 then
 set r to cuberoot(-q+sqrt(disc))
 set s to cuberoot(-q-sqrt(disc))

set ret to [r+s]
 else

 set ang to acos(-q/sqrt(-p*p*p))
 set r to 2*sqrt(-p)

set ret to []
 repeat with k=-1 to 1
 set theta 
to (ang - 2*pi*k)/3
 ret.add(r*cos(theta))
 end repeat

end if
 set ret to ret-a/3 --NB: this adds the value to each 
element
 return ret
end 

推荐答案

该错误似乎与您的solveCubic方法的参数名称有关.

The error appears to be with the names of the parameters of your solveCubic method.

您的书似乎在解释如何求解方程x 3 + ax 2 + bx + c =0.您在调用方法时以为参数abcd用于方程式ax 3 + bx 2 + cx + d =0.但是,事实证明您的方法主体实际上是在寻找方程dx 3   +  ax 2   +  bx  +  c  =  0.

It seems your book is explaining how to solve the equation x3 + ax2 + bx + c = 0. You are calling your method thinking that the parameters a, b, c and d are for the equation ax3 + bx2 + cx + d = 0. However, it turns out that the body of your method is actually finding solutions to the equation dx3 + ax2 + bx + c = 0.

除此命名错误外,计算似乎是正确的.如果您不相信我,请尝试将≈-1.858的值插入2x 3 + 5x 2 + 4x + 3.

Aside from this naming error, the calculations appear to be correct. Try plugging your value ≈-1.858 into 2x3 + 5x2 + 4x + 3 if you don't believe me.

如果您改为将solveCubic方法声明为

If you instead declare your solveCubic method as

public static double[] solveCubic(double d, double a, double b, double c) {

然后,参数对应于方程dx 3 + ax 2 + bx + c.然后,您应该发现您的方法可以为您提供期望的答案.

the parameters then correspond to the equation dx3 + ax2 + bx + c. You should then find that your method gives you the answer you expect.

这篇关于在Java中求解三次方程式时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆