I am trying to write a program to solve a quadratic equation whose coefficients\' values do not exceed 100 by absolute value and it is guaranteed that if any roots exist, they a
It's not a bug. Here:
(-b - std::sqrt(d)) / (2 * a)
The result of the expression is a double
. But result of 2 * a
is an int
and it's eventually converted to a double
. It is possible that 2 * a
overflows if a
is too large before it's converted to double
. But since the eventual result is already a double
, you could cast 2
or a
to double
as well and avoid the risk of overflow once and for all. So the compiler is telling you that the Right ThingTM to do is:
(-b - std::sqrt(d)) / (2.0 * a)
It won't overflow (result of (2.0 * a)
is a double
) and it's probably already what you want.
The root cause here (pun very much accepted) is that the quadratic equation is not a Diophantine equation. It applies to real numbers, and in particular sqrt(d)
is usually not an integer.
In C++, the return type of sqrt(IntegralType)
is double
. Thus 2*a
is converted to double
too, but only after multiplying. And Visual Studio very reasonably notes that you're better off doing the conversion before multiplying. It just doesn't note that you can even make a,b,c
all doubles from the start.
The way to fix this is to static_cast<long long>
because long long is 8 bytes and it is large enough to hold the information in the event of an overflow. An overflow occurs when you try to hold a number when you do not have enough bits to do so and as a result some of them get chopped off.
Here is an example without the warning:
std::cout << "Two roots: " << (-b - std::sqrt(d)) / (2 * static_cast<long long>(a)) << " "
<< (-b + std::sqrt(d)) / (2 * static_cast<long long>(a));