C++ 中 sqrt() 函数的问题

Ved*_*tra 3 c++ c++17

因此,我用 C++ 编写代码,这需要一个中间步骤来检查数字是否是完全平方数。我写了下面的代码。

int sqrt_of_t = (int)sqrt(t);
if (sqrt_of_t*sqrt_of_t != t)
{
    cout << "NO" << endl;
}
Run Code Online (Sandbox Code Playgroud)

这段代码在我的系统中给出了正确的结果,但是当它通过 Codeforces 中的在线判断时却失败了。失败的情况没有任何与之相关的溢出或任何东西(非常小的测试用例)。那么,任何人都可以解释一下哪里出了问题,并建议一些替代方法来检查数字是否是完全平方数,该方法适用于所有系统,并且不会显示这样的行为。这里t也是一个 int。

Joh*_*nck 5

sqrt()返回一个浮点数,将其转换为 int,这会截断任何小数部分。问题是浮点不能准确地表示所有整数,因此您最终可能会得到类似 19.99999999999999 的结果,您希望它是 20,但转换为整数时实际上是 19。

要修复它,请使用舍入代替:

long sqrt_of_t = lrint(sqrt(t));
Run Code Online (Sandbox Code Playgroud)

  • IEEE 标准要求“std::sqrt”从无限精确的结果中正确舍入。特别是,如果可以用浮点类型表示,则可以产生精确的结果。如果 `sqrt(400)` 返回类似 19.99999999999999 的内容,那么它就被破坏了。 (2认同)