#include
#include
#include
#include
/**
*
* @brief 牛顿迭代法求解
* @param [in]要开方的数
* @return 开方后的结果
*
*/
double sqrt_1(double dNum)
{
double dVal, dLastVal;
assert(dNum > 1e-12);
dVal = 1.0;
do {
dLastVal = dVal;
dVal = (dLastVal + dNum / dLastVal) / 2.0;
} while (dVal != dLastVal);
return dVal;
}
/**
*
* @brief 暴力
* @param [in]要开方的数
* @return 开方后的结果
*
*/
double sqrt_2(double dNum)
{
double i;
assert(dNum > 1e-12);
for (i = 0.0; fabs(i * i - dNum) >= 1e-4; i += 1e-6) ;
return i;
}
/**
*
* @brief 雷神之锤中底层代码
* @param [in]要开方的数
* @return 开方后的结果
*
*/
double sqrt_3(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i >> 1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return 1.0 / (double)x;
}
/**
*
* @brief 二分法找到合适解
* @param [in]要开方的数
* @return 开方后的结果
*
*/
double sqrt_4(double x)
{
double l = 0.0;
double r = x;
double m;
assert(x > 1e-12);
while (fabs(m * m - x) > 1e-4) {
m = (l + r) / 2.0;
if (m * m - x < 1e-12) {
l = m;
} else {
r = m;
}
}
return l;
}
int main(void)
{
double num;
while (scanf("%lf", &num) != EOF) {
printf("1. %.4f\n", sqrt_1(num));/* 牛顿迭代法 */
printf("2. %.4f\n", sqrt_2(num));/* 暴力*/
printf("3. %.4f\n", sqrt_3((float)num));/* 神奇算法*/
printf("4. %.4f\n", sqrt_4(num));/* 二分*/
}
return 0;
}
牛顿迭代法求平方根(Newton's Method)
/**
* 求平方根
* @param d 待开方数
* @param precision 算术平方根的精度
* @return
*/
double sqrt(double d,double precision) {
double x1 = d/2, x2 =(x1 + d/x1)/2;
while(Math.abs(x2 -x1)>precision) {
x1 = x2;
x2 =(x1 + d/x1)/2;
}
return x1;
}