前几天在网上看到有人晒一道面试题,写一个函数求平方根,该函数带2个参数,第一个参数是目标数字,第二个参数是精度。即:
double sqrt(double target, double g);
a = sqrt(t, g);
// 要求 |a^2 - t| < g
原文看到题目,就没有接着往下看,想了一会儿,就有思路了,觉得拿来做面试题不错。可是没想到面了好几个人,都没有人能给出稍微好看点的代码。难道大家工作久了之后,写代码反而生疏了吗?一直手痒,今晚就花了几分钟实现了一下,感觉还是比较简单的。实现完成之后,感觉不错,给出的答案都满足要求了,程序应该是对了。但是后来仔细一思考,又打了些程序处理过程的trace出来,发现不对了,有bug. 什么bug呢?收敛比较慢,和原来二分查找的设想不一样。虽然也能给出结果,但是收敛慢了,程序的实现和自己的思路不一致。想了一会儿,给出了正确的代码。该sqrt函数实现大约24行左右,如下:
#include <iostream>
using namespace std;
#define abs(X) ((X) > 0 ? (X) : -(X))
double sqrt(double target, double g)
{
if (target < 0 || g < 0) return -1;
double result = target;
double small = target > 1 ? 0 : target;
double big = target > 1 ? target : 1;
while (true) {
double diff = result * result - target;
if (abs(diff) < g) {
break;
}
else if (diff > 0) {
big = result;
}
else if (diff < 0) {
small = result;
}
result = (big + small) / 2;
}
return result;
}
int main()
{
cout << "sqrt(10, 0.1) = " << sqrt(10, 0.1) << endl;
cout << "sqrt(25, 0.001) = " << sqrt(25,0.001) << endl;
cout << "sqrt(0.09, 0.001) = " << sqrt(0.09, 0.001) << endl;
cout << "sqrt(0.4, 0.01) = " << sqrt(0.4, 0.01) << endl;
return 0;
}