整数开平方

来源:互联网 发布:国产汽车销售数据 编辑:程序博客网 时间:2024/09/21 08:55

如何判断一个数是不是完全平方数?最简单的方法是通过下面的代码:

可能有人会担心,Math.sqrt是浮点运算,会不会由于精度的问题,造成x与实际值不等?比如开方应得2,但是实际得到1.9999999,取整后只得到1。这个担心是完全没有必要的。java文档里明确说明:结果为最接近该参数值的实际数学平方根的double 值。一个int值总是能够精确地用double值表示。最接近2的double值一定是2.0

 但是如果n是一个long类型,那么上面的方法可能就不适用了。因为double最多有十几位有效数字,所以对于特别大的long值,没有办法精确地用double值表示。那么如何判断一个long值是不是完全平方数呢? 更进一步,如何求出一个long值(或int值)的平方根的整数部分呢?

 

一种可行的方法,是利用公式 1+3+5+...+(2n-1) = n*n

对于n是long的情况,只需把代码中的int改成long即可。(下同)

这个方法的缺点是比较慢,时间复杂度为O(sqrt(n))

 

一个比较快的方法是二分法,时间复杂度为O(log(n))

不幸的是,这个代码非常不容易写对,比如下面就是一种错误的写法:

 

 

一种基本上正确的写法如下。其思想是总是保证 low <= sqrt(n), up > sqrt(n):

这个代码在n较小的时候没什么问题。但是在对比较大的数,比如1000000求根的时候,得到的不是1000,而是458753。

原因在于在中间的计算过程中,x*x可能会溢出。比如在第一次循环的时候,x=(1000000+0)/2=500000,x*x已经超出了int的范围。另外(up+low)是不是也存在着溢出的可能呢?

 

把程序改成下面这个样子就完全没有问题了:

原创粉丝点击