我可以依靠它来判断C++中的平方数吗?

5 c++ math floating-point perfect-square

我能依靠吗?

sqrt((float)a)*sqrt((float)a)==a
Run Code Online (Sandbox Code Playgroud)

要么

(int)sqrt((float)a)*(int)sqrt((float)a)==a
Run Code Online (Sandbox Code Playgroud)

检查一个数字是否是一个完美的正方形?为什么或者为什么不?
int a是要判断的数字.我正在使用Visual Studio 2005.

编辑:感谢所有这些快速答案.我看到我不能依赖浮点型比较.(如果我如上所述,最后a会被隐式地转换为浮动吗?)如果我这样做的话

(int)sqrt((float)a)*(int)sqrt((float)a) - a < e  
Run Code Online (Sandbox Code Playgroud)

我应该多小才能获得这个e价值?

编辑2:嘿,我们为什么不把比较部分放在一边,并决定是否(int)有必要?正如我所看到的那样,对于正方形而言,差异可能很大; 但没有它,非正方形的差异可能很小.也许两者都不会.:-(

wig*_*igy 15

实际上,这不是一个C++,而是一个数学问题.

  1. 对于浮点数,您永远不应该依赖于相等.你要测试a == b的地方,只需测试abs(a - b)<eps,其中eps是一个小数字(例如1E-6),你可以将其视为一个足够好的近似值.
  2. 如果您正在测试的数字是整数,您可能会对Wikipedia关于整数平方根的文章感兴趣

编辑:

正如Krugar所说,我链接的文章没有回答任何问题.当然,那里没有你问题的直接答案,phoenie.我只是认为你的根本问题是浮点精度,也许你想要一些数学背景来解决你的问题.

对于不耐烦的人,文章中有一个关于实施isqrt冗长讨论的链接.归结为他的答案中贴出的代码karx11erx.

如果您的整数不符合无符号长整数,则可以自行修改算法.


Sha*_*men 5

如果您不想依赖浮点精度,那么您可以使用以下使用整数数学的代码.

Isqrt取自这里,是O(log n)

// Finds the integer square root of a positive number
static int Isqrt(int num)
{
    if (0 == num) { return 0; }  // Avoid zero divide
    int n = (num / 2) + 1;       // Initial estimate, never low
    int n1 = (n + (num / n)) / 2;
    while (n1 < n)
    {
        n = n1;
        n1 = (n + (num / n)) / 2;
    } // end while
    return n;
} // end Isqrt()

static bool IsPerfectSquare(int num)
{
    return Isqrt(num) * Isqrt(num) == num;
}
Run Code Online (Sandbox Code Playgroud)


Nik*_*iko -2

首先是基础知识:

如果您在计算中使用 (int) 数字,它将删除所有逗号后的数据。如果我没记错的话,如果你在任何计算中都有一个 (int) (+/-*),它会自动假定所有其他数字都是 int 。

因此,在您的情况下,您希望在涉及的每个数字上浮动,否则您将丢失数据:

sqrt((float)a)*sqrt((float)a)==(float)a
Run Code Online (Sandbox Code Playgroud)

是你想要走的路

  • 最近的一个问题表明,即使 sin(x)==sin(x) 也不总是成立。不要相信浮点比较。 (4认同)