二分法求解平方根的“陷阱”
来源:互联网 发布:网络播放平台排行榜 编辑:程序博客网 时间:2024/05/17 03:28
对于一个整数求解其平方根可以使用“二分法”和“牛顿法”。
所谓“二分法”就是不断地缩小平方根所在的范围,直到收敛到一个数。例如求解数k的平方根t,首先设置t的范围为[left, right](其中left和right分别初始化为1, k),然后判断m=(l+k)/2与k的平方根t的关系,如果m比t小,则t的范围为[m+1, right],否则为[left, m-1],然后依次循环,直到left>=right终止。
相比较于“牛顿法”,“二分法”比较直观,简单,而且通过程序极易实现,程序核心代码如下:
int left = 1, right = k;
int root = 0;
while(left < right) {
int mid = (left + right) / 2;
if(mid == k / mid) {
return mid;
} else if (mid > k / mid) {
right = mid - 1;
} else {
left = mid + 1;
root = mid; //不能完全开方是找到平方根的整数部分
}
}
通过观察代码,我们可以发现其中有两处地方值得考虑(代码中红线标出的部分),对于第一处判断可能很多人潜意识的会写成“mid * mid == k”,而第二处写成“mid * mid > k”,初看,这个貌似的确没有什么问题,但是在运行程序时可能会发现出现死循环现象。
为什么会出现这种情况呢?
主要是因为在计算机中整型数据(int)是有位数限制的,一般是4个字节(32bits),这就可能出现“mid * mid”溢出的情况,这样在程序执行过程中就可能出现无限循环的情况。
因此,以后在程序设计过程中一定要特别注意不同类型数的位数的限制,避免因为溢出造成的逻辑错误,而且在能够同时使用乘法或者除法(注意考虑除数不能为0)时,尽量使用除法计算。
非常感谢xuqing-ict指出的问题,在做运算时,不仅要避免乘法可能会带来的问题,还需要考虑到加法可能或造成的溢出问题,对于“二分法”算法中求解"mid=left+right"就需要考虑右边可能因为溢出造成的结果错误,因此应该改成"mid=left+(right-left)/2".
1 0
- 二分法求解平方根的“陷阱”
- 二分法求解非负数的平方根
- 平方根的高效求解
- 【Leetcode】求解2的平方根
- 求解一个数字的平方根,不用平方根库函数。
- 二分法求解方程的解
- 二分法求平方根
- 二分法做平方根
- 求平方根的方法(牛顿迭代法和二分法)
- 二分法求解数列中最小的数
- 二分法求解方程的值 matlab
- 牛顿迭代法求解平方根
- 牛顿迭代法求解平方根
- 高效求解平方根的倒数的函数实现
- Quake III中不可思议的求解平方根实现方法
- 简单题-不用库函数,求解一个数字的平方根
- Doom3 平方根求解算法的个人领悟 欢迎来讨论
- Leetcode练习<二十一>求解整数的平方根
- Listview 异步加载图片 快速滑动发生图片错误的解决办法 复用convertview
- Closest Common Ancestors+poj+最近公共祖先
- 基于github搭建个人主页
- 谈几点我认识的java与PHP的不同和相同
- android下大文件分割上传
- 二分法求解平方根的“陷阱”
- 创业团队的招聘与留人
- 黄晓明工作室招聘工厂工作总结
- 班主任工作总结 初中物资管理工作总结
- 美国工作签证热敏电阻工作原理
- 工作签证北京工作服定做
- 工作描述范文年级组工作计划
- 工作检查书范文工作简历怎么写
- 工作汇报格式驻村工作总结