0

I referred to this post for complex number roots of a quadratic equation. Solve Quadratic Equation in C++

So, I wrote something similiar in C++ using OpenCV and std libraries, but I am always getting NaN and dont know why.

cv::Vec3f coefficients(1,-1,1);
cv::Vec<std::complex<float>,2> result_manual = {{0,0},{0,0}};

float c = coefficients.operator()(0);
float b = coefficients.operator()(1);
float a = coefficients.operator()(2);

std::cout << "---------manual method solving quadratic equation\n";
double delta;
delta = std::pow(b,2)-4*a*c;
if ( delta < 0) {
    result_manual[0].real(-b/(2*a));
    result_manual[1].real(-b/(2*a));
    result_manual[0].imag((float)std::sqrt(delta)/(2*a));
    result_manual[1].imag((float)-std::sqrt(delta)/(2*a));
}
else {
    result_manual[0].real((float)(-b + std::sqrt(delta))/2*a);
    result_manual[1].real((float)(-b - std::sqrt(delta))/2*a);
}
std::cout << result_manual[0] << std::endl;
std::cout << result_manual[1] << std::endl;

Result

---------manual method solving quadratic equation
(0.5,-nan)
(0.5,nan)
infoclogged
  • 3,641
  • 5
  • 32
  • 53
  • 4
    Just a guess, but if `delta` is negative, `sqrt(delta)` will return NaN, right? – PaulR Sep 05 '17 at 15:43
  • 1
    You need to check what delta is. If it is negative then `sqrt` is not going to work – NathanOliver Sep 05 '17 at 15:43
  • @NathanOliver : the link that I posted in my question is doing a sqrt on a negative number and its an accepted answer. – infoclogged Sep 05 '17 at 15:49
  • 1
    @infoclogged So, have a look at the documentation of [`std::sqrt`](http://en.cppreference.com/w/cpp/numeric/math/sqrt): "_If the argument is less than -0, FE_INVALID is raised and **NaN is returned**._". The answer is marked as accepted by the OP of the linked question. Maybe the answer solved the issue for _them_, so they marked it as accepted. – Algirdas Preidžius Sep 05 '17 at 15:53
  • 1
    @infoclogged I left them a comment as that is not the correct way to do this. You need to take the absolute value of delta and get the square root of that for the imaginary part. – NathanOliver Sep 05 '17 at 15:54
  • @NathanOliver : what a pain.. thanks.. I will delete this post . – infoclogged Sep 05 '17 at 15:56

1 Answers1

0

Answering myself just for the completion, after many useful comments.

The link in the question is a wrong implementation as the sqrt of a negative number is not defined. The correct implementation would be

    result_manual[0].imag((float)-std::sqrt(std::abs(delta))/(2*a));
    result_manual[1].imag((float)std::sqrt(std::abs(delta))/(2*a));
infoclogged
  • 3,641
  • 5
  • 32
  • 53
  • 2
    since your code is already checking to see if delta < 0, it is more accurate to use `(-delta)` vs. calling `abs` on a number you already know is negative. – franji1 Sep 05 '17 at 16:45