在另一个不相关的互联网论坛上,有人询问如何检查给定数字的平方根是否为整数。现在本身就是一个微不足道的家庭作业问题,但我开始怀疑这种天真的方法在所有情况下是否都是正确的。也就是说,在伪代码中:
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
本身不是一个整数(或一个不是另一个整数的平方的整数)但是{由于浮点错误,{1}} 会是和整数吗?
答案 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.