1

在另一个不相关的 Internet 论坛上,有人询问如何检查给定数字的平方根是否为整数。现在,这本身就是一个微不足道的家庭作业问题,但我开始怀疑这种幼稚的方法是否在所有情况下都是正确的。也就是说,在伪代码中:

declare x, y as double
input x
y = sqrt(x)
if round(y) = y then
    output "Is integer"
else
    output "Isn't integer"

是否可以输入这样的x,它x本身不是整数(或不是另一个整数的平方的整数),而是由于浮点错误而sqrt(x) 成为整数?

4

5 回答 5

8

是:当 x 在Machine epsilon的边缘时。考虑 x = 1.00...0001,它仍然可以二进制形式表示,与 1.0 不同。这个数字的平方根将给出 1.0,产生假阳性。

于 2011-09-26T08:09:05.443 回答
4

nextafter(1.0)下一个大于 1.0(在 C 中)的可表示浮点数的平方根可以合理地计算为 1.0。

于 2011-09-26T08:09:17.377 回答
0

首先,如果数字太大以至于精度不会延伸到小数点,那么你只会得到整数,但它们不正确,所以我想你不关心这种情况。

关于确切结果:如果您有 IEE754 浮点数,这应该很容易测试。只需取一个完美整数平方的 double,将其二进制表示形式递增或递减一位,然后检查平方根是否为精确整数。我相信,标准浮点运算需要精确到最后一个 0.5 个单位,因此整数实际上可能是正确的最接近的可表示平方根。

于 2011-09-26T08:10:51.497 回答
0

当然:

double d = Math.Sqrt(4.000000000000001);
Console.WriteLine(d == 4);
Console.WriteLine(d == 2);

这导致(C#)

False
True
于 2011-09-26T08:12:15.600 回答
0

将 x 作为像 1+epsilon 这样的浮点数当然会起作用。但是对于非平方整数,它也适用于整数足够大的情况。

例如 (c#)

ulong i = ulong.MaxValue; // 2^64-1, a non square integer.
double s = Math.Sqrt(i);  // Very nearly 2^32
bool same = Math.Round(s) == s; // true, s is close enough to 2^32.
于 2011-09-26T08:51:13.947 回答