Arithmetic overflow: Using operator '*' on a 4 byte value then casting the result to a 8 byte value

前端 未结 3 1305
温柔的废话
温柔的废话 2021-01-24 08:08

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

相关标签:
3条回答
  • 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.

    0 讨论(0)
  • 2021-01-24 08:15

    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.

    0 讨论(0)
  • 2021-01-24 08:32

    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));
    
    
    0 讨论(0)
提交回复
热议问题