Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 解析解三次方程的函数_Javascript_Algorithm_Math - Fatal编程技术网

Javascript 解析解三次方程的函数

Javascript 解析解三次方程的函数,javascript,algorithm,math,Javascript,Algorithm,Math,我需要解析地和实数地解一个三次方程(ax^3+bx^2+c*x+d=0),最好是用纯javascript(无libs)。由于可能有1到3个根,我认为数字数组是一种合理的结果类型 p.S.在下面提供了我自己的解决方案,希望它会有用。给你。包括处理退化案件。主要算法主要是从 函数cuberoot(x){ 变量y=数学功率(数学绝对值(x),1/3); 返回x

我需要解析地和实数地解一个三次方程(ax^3+bx^2+c*x+d=0),最好是用纯javascript(无libs)。由于可能有1到3个根,我认为数字数组是一种合理的结果类型


p.S.在下面提供了我自己的解决方案,希望它会有用。

给你。包括处理退化案件。主要算法主要是从

函数cuberoot(x){
变量y=数学功率(数学绝对值(x),1/3);
返回x<0?-y:y;
}
函数(a、b、c、d){
如果(数学abs(a)<1e-8){//二次型,ax^2+bx+c=0
a=b;b=c;c=d;
如果(数学abs(a)<1e-8){//线性情况,ax+b=0
a=b;b=c;
if(Math.abs(a)<1e-8)//退化情形
返回[];
返回[-b/a];
}
变量D=b*b-4*a*c;
if(数学abs(D)<1e-8)
回报率[-b/(2*a)];
否则,如果(D>0)
返回[(-b+数学sqrt(D))/(2*a),(-b-数学sqrt(D))/(2*a)];
返回[];
}
//转换为下压立方t^3+pt+q=0(子矩阵x=t-b/3a)
var p=(3*a*c-b*b)/(3*a*a);
变量q=(2*b*b*b-9*a*b*c+27*a*a*d)/(27*a*a*a*a);
变种根;
if(Math.abs(p)<1e-8){//p=0->t^3=-q->t=-q^1/3
根=[cuberoot(-q)];
}如果(数学abs(q)<1e-8){//q=0->t^3+pt=0->t(t^2+p)=0
根=[0].concat(p<0?[Math.sqrt(-p),-Math.sqrt(-p)]:[]);
}否则{
var D=q*q/4+p*p*p/27;
if(Math.abs(D)<1e-8){//D=0->两个根
根=[-1.5*q/p,3*q/p];
}else如果(D>0){//只有一个实根
var u=cuberoot(-q/2-数学sqrt(D));
根=[u-p/(3*u)];
}else{//D<0,三个根,但需要使用复数/三角解
var u=2*数学sqrt(-p/3);
var t=Math.acos(3*q/p/u)/3;//D<0表示p<0,acos参数在[-1..1]
var k=2*Math.PI/3;
根=[u*Math.cos(t),u*Math.cos(t-k),u*Math.cos(t-2*k)];
}
}
//从下压立方转换回
对于(var i=0;i
Complex root?这个问题似乎离题了,因为它是关于让别人为你做工作的。@duffymo:注意,答案是同一个用户;事实上,他正在做这项工作,并将其发布在这里,我认为这个问题似乎是一个要求。谢谢@PhilH,我编辑了这个问题,明确表示我已经完成了这项工作,并将其分享给大家。假设它能起作用,这是写作的道具!我可能建议你编辑这个问题;我认为它吸引了反对票,因为它似乎要求一个没有工作的答案,而事实上你在这里提供答案,你已经完成了工作!硬编码ε是一个糟糕的做法。非常感谢。我把它移植到php,它工作得很好。我找到的最佳解决方案。为什么要使用“是”,以避免舍入错误。请根据您的应用需要随时调整ε。
function cuberoot(x) {
    var y = Math.pow(Math.abs(x), 1/3);
    return x < 0 ? -y : y;
}

function solveCubic(a, b, c, d) {
    if (Math.abs(a) < 1e-8) { // Quadratic case, ax^2+bx+c=0
        a = b; b = c; c = d;
        if (Math.abs(a) < 1e-8) { // Linear case, ax+b=0
            a = b; b = c;
            if (Math.abs(a) < 1e-8) // Degenerate case
                return [];
            return [-b/a];
        }

        var D = b*b - 4*a*c;
        if (Math.abs(D) < 1e-8)
            return [-b/(2*a)];
        else if (D > 0)
            return [(-b+Math.sqrt(D))/(2*a), (-b-Math.sqrt(D))/(2*a)];
        return [];
    }

    // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)
    var p = (3*a*c - b*b)/(3*a*a);
    var q = (2*b*b*b - 9*a*b*c + 27*a*a*d)/(27*a*a*a);
    var roots;

    if (Math.abs(p) < 1e-8) { // p = 0 -> t^3 = -q -> t = -q^1/3
        roots = [cuberoot(-q)];
    } else if (Math.abs(q) < 1e-8) { // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0
        roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []);
    } else {
        var D = q*q/4 + p*p*p/27;
        if (Math.abs(D) < 1e-8) {       // D = 0 -> two roots
            roots = [-1.5*q/p, 3*q/p];
        } else if (D > 0) {             // Only one real root
            var u = cuberoot(-q/2 - Math.sqrt(D));
            roots = [u - p/(3*u)];
        } else {                        // D < 0, three roots, but needs to use complex numbers/trigonometric solution
            var u = 2*Math.sqrt(-p/3);
            var t = Math.acos(3*q/p/u)/3;  // D < 0 implies p < 0 and acos argument in [-1..1]
            var k = 2*Math.PI/3;
            roots = [u*Math.cos(t), u*Math.cos(t-k), u*Math.cos(t-2*k)];
        }
    }

    // Convert back from depressed cubic
    for (var i = 0; i < roots.length; i++)
        roots[i] -= b/(3*a);

    return roots;
}