problem with a cubic function code

I am a beginner with c++ and am experimenting with functions. I am trying to create a code that gives you the zero(s) of a cubic functions when you enter the a, b, c, and d values. For some reason it keeps saying there is an error. If anyone knows what is wrong with my code please tell me because I am very confused.
Thanks a lot,
Diego315

code:
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;

float cubicz (float a, float b, float c, float d)
{
float z =

cbrt((-(pow(b,3))/(27*(pow(a,3)))+((b*c)/(6*(pow(a,2))))+
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b,2))/(9*(pow(a,2)))))))+
cbrt((-(pow(b,3))/(27*(pow(a,3)))+((b*c)/(6*(pow(a,2))))-
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b,2))/(9*(pow(a,2)))))))-
((b)/(3*a));
return z;
}

int main ()
{
cout << ("enter the 'a' value: ");
float a;
cin >> a;
cout << ("enter the 'b' value: ");
float b;
cin >> b;
cout << ("enter the 'c' value: ");
float c;
cin >> c;
cout << ("enter the 'd' value: ");
float d;
cin >> d;
float ans;
ans = cubicz (a, b, c, d);
cout << ans;

}

Error Message:
main.cpp: In function ‘float cubicz(float, float, float, float)’:
main.cpp:11:44: error: no matching function for call to ‘pow(__gnu_cxx::__promote_2::__type)’
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b,2))/(9*(pow(a,2)))))))+
^
In file included from /usr/include/features.h:374:0,
from /usr/include/x86_64-linux-gnu/c++/5/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:482,
from /usr/include/c++/5/iostream:38,
from main.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:153:1: note: candidate: double pow(double, double)
__MATHCALL (pow,, (_Mdouble_ __x, _Mdouble_ __y));
^
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:153:1: note: candidate expects 2 arguments, 1 provided
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:434:5: note: candidate: template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type std::pow(_Tp, _Up)
pow(_Tp __x, _Up __y)
^
/usr/include/c++/5/cmath:434:5: note: template argument deduction/substitution failed:
main.cpp:11:44: note: candidate expects 2 arguments, 1 provided
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b,2))/(9*(pow(a,2)))))))+
^
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:411:3: note: candidate: constexpr long double std::pow(long double, long double)
pow(long double __x, long double __y)
^
/usr/include/c++/5/cmath:411:3: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/5/cmath:407:3: note: candidate: constexpr float std::pow(float, float)
pow(float __x, float __y)
^
/usr/include/c++/5/cmath:407:3: note: candidate expects 2 arguments, 1 provided
main.cpp:13:44: error: no matching function for call to ‘pow(__gnu_cxx::__promote_2::__type)’
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b^2))/(9*(pow(a,2)))))))-
^
In file included from /usr/include/features.h:374:0,
from /usr/include/x86_64-linux-gnu/c++/5/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:482,
from /usr/include/c++/5/iostream:38,
from main.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:153:1: note: candidate: double pow(double, double)
__MATHCALL (pow,, (_Mdouble_ __x, _Mdouble_ __y));
^
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:153:1: note: candidate expects 2 arguments, 1 provided
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:434:5: note: candidate: template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type std::pow(_Tp, _Up)
pow(_Tp __x, _Up __y)
^
/usr/include/c++/5/cmath:434:5: note: template argument deduction/substitution failed:
main.cpp:13:44: note: candidate expects 2 arguments, 1 provided
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b^2))/(9*(pow(a,2)))))))-
^
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:411:3: note: candidate: constexpr long double std::pow(long double, long double)
pow(long double __x, long double __y)
^
/usr/include/c++/5/cmath:411:3: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/5/cmath:407:3: note: candidate: constexpr float std::pow(float, float)
pow(float __x, float __y)
^
/usr/include/c++/5/cmath:407:3: note: candidate expects 2 arguments, 1 provided
main.cpp:13:66: error: invalid operands of types ‘float’ and ‘int’ to binary ‘operator^’
sqrt((pow((-(pow(b,3)))/(27*(pow(a,3)))),2)+((c/(3*a)-(pow(b^2))/(9*(pow(a,2)))))))-
^
Last edited on
A few problems... first, I suggest doing the quadratic formula, and being comfortable with that, before you try to tackle the cubic formula. Really.

1. pow() takes in two arguments.
pow(x,y) means xy.

2. ^ does not mean exponentiation in C++, it means XOR (exclusive OR). You shouldn't be using it here.

In other words, pow(b^2) doesn't make any sense. You mean pow(b, 2).

For small integer powers, it is often better to just do multiplication. i.e. do x * x instead of pow(x, 2), but it doesn't actually matter that much for just learning purposes.

BTW, I didn't actually check your math, but note that the full solution to finding the roots of a cubic equation is more complicated than whatever you have there.
See: https://en.wikipedia.org/wiki/Cubic_function#General_solution_to_the_cubic_equation_with_real_coefficients

Good luck.. let us know if you run into more trouble.
Last edited on
you know its a cubic. you know its derivative. newtons method would be like 20 lines of code here... this looks like the hard way.
Last edited on
jonnin what would be fun is having the output be in symbolic, exact notation :D
It's fun to do for quadratic but it's like 10x more complicated to do for cubic.
diego315,

A cubic equation has 3 roots (sometimes repeated, and sometimes complex rather than real). I see no evidence in your code that you could return THREE roots, not just one, nor that you are checking for complex roots. You might be trying to reproduce Cardano's original expression (incorrectly), but taking square roots of negative numbers isn't recommended.

There are two common ways of writing the solution of cubic equations: one involving square and cube roots (which is the approach you appear to be taking), the other involving trigonometric functions. The latter is more reliable.

Try to simplify your code - there is a large amount of repetition, and at one point you have SEVEN successive brackets; that makes it unreadable. What you currently have inside a square root should give rise to a discriminant, which - as for a quadratic - will determine if some roots are complex.
Last edited on
Okay thank you very much
You can find the full method here:
https://imgur.com/a/kX2mno3

Coded, it looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cmath>
using namespace std;


int main()
{
   const double PI = 4 * atan( 1.0 );

   double a, b, c, d;
   cout << "Solve ax^3 + bx^2 + cx + d = 0    ( a/=0, b, c, d all real)\n";
   cout << "\nInput a b c d (separated by spaces): ";
   cin >> a >> b >> c >> d;

   // Reduced equation: X^3 - 3pX - 2q = 0, where X = x-b/(3a)
   double p = ( b * b - 3 * a * c ) / ( 9 * a * a );
   double q = ( 9 * a * b * c - 27 * a * a * d - 2 * b * b * b ) / ( 54 * a * a * a );
   double offset = b / ( 3 * a );
   double discriminant = q * q - p * p * p;           // Discriminant; determines the nature of the roots

   cout << "\nRoots:\n";
   if ( discriminant < 0 )      // set X = 2 sqrt(p) cos(theta); compare 4 cos^3(theta)-3 cos(theta) = cos(3 theta)
   {
      double theta = acos( q / ( p * sqrt( p ) ) );
      double r = 2 * sqrt( p );
      for ( int n = 0; n < 3; n++ )                   // Three real roots
      {
         cout << r * cos( ( theta + 2 * n * PI ) / 3 ) - offset << '\n';
      }
   }
   else                                               // Use Cardano/Tartaglia's expression 
   {
      double gamma1 = cbrt( q + sqrt( discriminant ) );
      double gamma2 = cbrt( q - sqrt( discriminant ) );

      cout << gamma1 + gamma2 - offset << '\n';       // Real root

      double re = -0.5 * ( gamma1 + gamma2 ) - offset;
      double im =  0.5 * ( gamma1 - gamma2 ) * sqrt( 3.0 );
      if ( discriminant == 0.0 )                      // Equal roots (hmmm, floating point ...)
      {
         cout << re << '\n';
         cout << re << '\n';
      }
      else                                            // Two complex roots
      {
         cout << re << " + " << im << " i\n";
         cout << re << " - " << im << " i\n";
      }
   }
}


Solve ax^3 + bx^2 + cx + d = 0    ( a/=0, b, c, d all real)

Input a b c d (separated by spaces): 1 -6 11 -6
Roots:
3
1
2


Solve ax^3 + bx^2 + cx + d = 0    ( a/=0, b, c, d all real)

Input a b c d (separated by spaces): 1 -13 60 -100
Roots:
5
4 + 2 i
4 - 2 i



If you want the THREE cube roots of 1.0 (one real, two complex):
Solve ax^3 + bx^2 + cx + d = 0    ( a/=0, b, c, d all real)

Input a b c d (separated by spaces): 1 0 0 -1
Roots:
1
-0.5 + 0.866025 i
-0.5 - 0.866025 i
Last edited on
Topic archived. No new replies allowed.