Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8708489
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T04:09:08+00:00 2026-06-13T04:09:08+00:00

As part of my project I need to solve a quartic polynomial in a

  • 0

As part of my project I need to solve a quartic polynomial in a closed form in C++.

A*x4 + B*x3 + C*x2 + D*x + E = 0

I found several links to this end. One of them is here. But it computes all roots, while I want just real roots. The algorithms mainly use Ferrari’s method to reduce the order.

bool solveQuartic(double a, double b, double c, double d, double e, double &root)
{
// I switched to this method, and it seems to be more numerically stable.
// http://www.gamedev.n...topic_id=451048 

// When a or (a and b) are magnitudes of order smaller than C,D,E
// just ignore them entirely. This seems to happen because of numerical
// inaccuracies of the line-circle algorithm. I wanted a robust solver,
// so I put the fix here instead of there.
if(a == 0.0 || abs(a/b) < 1.0e-5 || abs(a/c) < 1.0e-5 || abs(a/d) < 1.0e-5)
    return solveCubic(b, c, d, e, root);

double B = b/a, C = c/a, D = d/a, E = e/a;
double BB = B*B;
double I = -3.0*BB*0.125 + C;
double J = BB*B*0.125 - B*C*0.5 + D;
double K = -3*BB*BB/256.0 + C*BB/16.0 - B*D*0.25 + E;

double z;
bool foundRoot2 = false, foundRoot3 = false, foundRoot4 = false, foundRoot5 = false;
if(solveCubic(1.0, I+I, I*I - 4*K, -(J*J), z))
{
    double value = z*z*z + z*z*(I+I) + z*(I*I - 4*K) - J*J;

    double p = sqrt(z);
    double r = -p;
    double q = (I + z - J/p)*0.5;
    double s = (I + z + J/p)*0.5;

    bool foundRoot = false, foundARoot;
    double aRoot;
    foundRoot = solveQuadratic(1.0, p, q, root);
    root -= B/4.0;

    foundARoot = solveQuadratic(1.0, r, s, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }

    foundARoot = solveQuadraticOther(1.0, p, q, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }

    foundARoot = solveQuadraticOther(1.0, r, s, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }
    return foundRoot;
}
return false;
}

This uses solveCubic() which gives both real and imaginary solution:

bool solveCubic(double &a, double &b, double &c, double &d, double &root)
{
if(a == 0.0 || abs(a/b) < 1.0e-6)
    return solveQuadratic(b, c, d, root);

double B = b/a, C = c/a, D = d/a;

double Q = (B*B - C*3.0)/9.0, QQQ = Q*Q*Q;
double R = (2.0*B*B*B - 9.0*B*C + 27.0*D)/54.0, RR = R*R;

// 3 real roots
if(RR<QQQ)
{
    /* This sqrt and division is safe, since RR >= 0, so QQQ > RR,    */
    /* so QQQ > 0.  The acos is also safe, since RR/QQQ < 1, and      */
    /* thus R/sqrt(QQQ) < 1.                                     */
    double theta = acos(R/sqrt(QQQ));
    /* This sqrt is safe, since QQQ >= 0, and thus Q >= 0             */
    double r1, r2, r3;
    r1 = r2 = r3 = -2.0*sqrt(Q);
    r1 *= cos(theta/3.0);
    r2 *= cos((theta+2*PI)/3.0);
    r3 *= cos((theta-2*PI)/3.0);

    r1 -= B/3.0;
    r2 -= B/3.0;
    r3 -= B/3.0; 

    root = 1000000.0;

    if(r1 >= 0.0) root = r1;
    if(r2 >= 0.0 && r2 < root) root = r2;
    if(r3 >= 0.0 && r3 < root) root = r3;

    return true;
}
// 1 real root
else
{
    double A2 = -pow(fabs®+sqrt(RR-QQQ),1.0/3.0);
    if (A2!=0.0) {
        if (R<0.0) A2 = -A2; 
        root = A2 + Q/A2; 
    }
    root -= B/3.0;
    return true;
}
}

Here are some links that explain the code. solveCubic and solveQuartic

Is there anyone who can modify the code to solve a quartic polynomial for real roots?

I want to implement it as efficiently as possible. BTW I’d appreciate if someone introduced a useful library for this purpose like LAPACK (it seems to be unable to calculate the roots of a quartic polynomial directly).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T04:09:09+00:00Added an answer on June 13, 2026 at 4:09 am

    Probably the most efficient way to solve this equation in closed form for real roots is to solve it in closed form for all roots and then discard the roots which are imaginary.

    You might think you could use try/catch pairs to determine if imaginary numbers are cropping up, but this isn’t a very good strategy because some of the intermediate values you generate in calculating a real root may be imaginary.

    Therefore, you could try using a C++ complex numbers library (see here or here) to do the calculations.

    Afterwards, check to see if the imaginary part of the number is non-zero and, if it is discard it. But remember, floating-point math is inexact, so “zero” includes a range of numbers which are very close to zero.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

so I need to maintain this old legacy project, where one part of it
The end goal of this part of my project is to be able to
As part of my project I need to use some Unamanged code dlls in
I need to reference a service that is a part of another project. I
I have split my project into several subprojects But all have a common part
In part of my project I need to compute orientation of a patch in
This is the situation: I'm working on a project where I need to be
I wanted to know what part of the project I need to copy for
As part of a small project I'm working on, I need to be able
In Visual Studio (C#) I have a form created as part of a project

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.