由于浮点舍入误差,非整数的平方根可以变成整数吗?

时间:2011-09-26 08:02:29

标签: math floating-point square-root

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

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

是否可以输入xx本身是一个整数(或一个不是另一个整数的平方的整数)但是{由于浮点错误,{1}} 会是和整数吗?

5 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:4)

下一个可表示的浮点数高于1.0(C中为nextafter(1.0))的平方根可能合理地评估为1.0。

答案 2 :(得分:0)

首先,如果数字太大而精度没有延伸到小数点,那么你只会得到整数,但它们不正确,所以我想你不关心那个案例

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

答案 3 :(得分:0)

当然:

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

这导致(C#)

False
True

答案 4 :(得分: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.