目录
简介
开根号算法
√n = a;
我们要求开根号的算法结果,实际上就是求a的值,所以,这里我们需要转换思维,也就是求满足a^2 = n中a的值.
原理
这里采用二分法,主要原理:
- 开平方的得到的结果数字,小于或者等于被开方数
- 而且中间数平方大于被开方数,则接下来缩小区域在中间值的左侧,反之在右侧;
- 存在的误差范围,如果在误差允许范围内,即可得到开放结果
代码
- (CGFloat)sqrtNumber:(CGFloat)number {
CGFloat sqrtNumber = 0;
if (number < 0) {
// 这里根据实际情况做处理,简单的返回-1,可以根据-1情况进行处理
sqrtNumber = -1;
} else {
// 下面是最主要的
// 定义变量
CGFloat oldRangeMid; // 记录上次运算的中间值
CGFloat newRangeMid; // 生成新的中间值
CGFloat rangeLeft; // 二分法区间的起始数
CGFloat rangeRight; // 二分法区间的截止数
// 初始化
rangeLeft = 0;
rangeRight = number;
newRangeMid = oldRangeMid = (rangeLeft + rangeRight) / 2;
do {
// 满足条件,二分法缩小判断范围
if (newRangeMid * newRangeMid > number) {
rangeRight = newRangeMid;
} else {
rangeLeft = newRangeMid;
}
// 重新赋值,判断并且是否进入下一步的运算
oldRangeMid = newRangeMid;
newRangeMid = (rangeRight + rangeLeft) / 2;
// 下面的判断是比较重要的
// 我们需要判断新的Mid的值和旧的Mid的值的差值是不是在Float的精确度的允许误差范围之内,
// 如果在误差范围之内,那么新的Mid就是我们需要得到的数值
// 如果不在误差范围之内,那么继续进入下一步的运算,一直到满足
} while (fabs(newRangeMid - oldRangeMid) > FLT_EPSILON);
// 满足结果,赋值
sqrtNumber = newRangeMid;
}
// 返回求得的开方数
return sqrtNumber;
}
补充:
FLT_EPSILON,这个是OC中的代表浮点的精确度,在c语言中,可以用eps.
#define FLT_EPSILON __FLT_EPSILON__
#define DBL_EPSILON __DBL_EPSILON__
#define LDBL_EPSILON __LDBL_EPSILON__