【发布时间】:2019-12-12 15:56:03
【问题描述】:
我正在尝试编写一个程序来求解系数值绝对值不超过 100 的二次方程,并且保证如果存在任何根,它们都是整数。这是我尝试过的:
#include <cmath>
#include <iostream>
int main() {
int a, b, c; // coefficients of quadratic equation
std::cin >> a >> b >> c;
int d = b * b - 4 * a * c; // discriminant
if (d < 0)
std::cout << "No roots";
else if (d == 0)
std::cout << "One root: " << -b / (2 * a);
else
std::cout << "Two roots: " << (-b - std::sqrt(d)) / (2 * a) << " "
<< (-b + std::sqrt(d)) / (2 * a);
return 0;
}
它工作正常,但是,Visual Studio 2019 显示此警告:
算术溢出:对 4 字节值使用运算符“*”,然后将结果转换为 8 字节值。在调用运算符 '*' 之前将值转换为更宽的类型以避免溢出 (io.2)。
到底为什么会弹出这个警告,它想告诉我什么?我做错了什么,我该如何解决这个问题?
我在 SO 上看到过 this,但我不认为这是一个错误。
【问题讨论】:
-
我不喜欢“铸造”这个词,因为没有。人们会期望编译器的创建者知道隐式转换和显式转换之间的区别。
-
这实际上不是一个错误。意思是
2 * a产生一个32 位的值,根据a的值,它可能会溢出。由于结果被转换为 64 位值(用于除法),因此建议您在乘法之前进行转换。您可以通过2.0 * a或2LL * a来修复它 -
“我不相信这是一个错误。” 为什么不呢?如果您对该页面上的问题或答案有批评,您应该在该页面上提出批评,而不是重新提出相同的问题。
-
@LightnessRaceswithMonica 这不是错误。例如,如果
a是 INT_MAX,2 * a会溢出,但2.0 * a不会溢出。无论如何,结果都会转换为double。所以2.0 * a基本上给出了相同的结果,但溢出的可能性要小得多。 -
嗯,其实是的,好吧。
标签: c++