欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C】库函数之sqrt

程序员文章站 2022-06-08 19:13:15
...

Compute square root

# include <math.h>
double sqrt(double x); 

   Value whose square root is computed.

   If the argument is negative, a domain error occurs.

  上述内容是C++官网对sqrt函数的介绍,可以看出sqrt函数用来求一个数字的平方根,并且该数字不能为负数,否则将会报错。

  接下来介绍两种实现sqrt函数的方法:

1、二分法

  既然sqrt函数是来求平方根的,不妨假设 x²=n ,从而将求平方根的过程转换为求解x的过程。将 x²=n 这个等式移项可以得到 x²-n=0 ,抽象化该等式,可以得到f(x)=x²-n=0,那么求解x的过程就转换成求解函数f(x)=x²-n与x轴的交点的横坐标的值。

   零点定理:若f(x)在(a,b)上连续,且f(a)*f(b)<0,则f(x)在(a,b)内至少有一个零点。

【C】库函数之sqrt

   不断地把函数f(x)的零点所在的区间一分为二,使得区间的两个端点逐步逼近零点,最后得到的零点的近似值就是x的值。

  算法思想:

a.首先使用二分法确定区间[left,right],其中left=0,right=n;

b.然后计算出该区间的中间位置mid=(left+right)/2;

c.判断mid*mid是否大于n,如果大于,则缩小[left,right]的范围为之前的一半,反之,则继续缩小[left,right]的范围为之前的一半;

d.设置一个变量last存放每次比较结束后mid的值,不断重复c,直到last与mid的误差满足一定条件时,返回last的值即为x。

  注意:计算mid=(left+right)/2时,加法运算会溢出,由于数据类型为浮点型,因此不考虑移位运算,这里可以使用mid=left+(right-left)/2来代替。给出几种常见计算平均值的方法

    源代码:

/*
*	函数名称:MySqrt
*
*	函数功能:求一个数字的平方根(二分法)
*
*	入口参数:num
*
*	出口参数:ret
*
*	返回类型:double
*/

double MySqrt(double num)
{
	double left = 0.0;
	double right = num;
	double mid = 0.0;
	double last = 0.0;

	mid = left + (right - left) / 2.0;

	assert(num >= 0);
	
	while (fabs(last - mid) > EXP)
	{
		if ((mid * mid) > num)
		{
			right = mid;
		}
		else
		{
			left = mid;
		}

		last = mid;
		mid = left + (right - left) / 2.0;
	}

	return last;
}

2、牛顿迭代法

【C】库函数之sqrt

   首先x²=n的解可以转化为求函数f(x)=x²-n与x轴的交点的横坐标的值。在x轴上任选一点x0,过点(x0,f(x0))作函数f(x)的切线交x轴于点x1,满足切线方程f(x0)=f'(x0)(x0-x1),代入f(x)=x²-n中可以得到迭代表达式x1=(x0 + n/x0)/2。不断地求切线方程对应的迭代表达式,最终只要满足求出的结果在定义的精度范围内即可。

  源代码:

/*
*	函数名称:MySqrt
*
*	函数功能:求一个数字的平方根(牛顿迭代法)
*
*	入口参数:num
*
*	出口参数:ret
*
*	返回类型:double
*/

double MySqrt(double num)
{
	double last = 0.0;
	double ret = num;

	assert(num >= 0);

	do
	{
		last = ret;
		ret = (ret + num / ret) / 2;
	}while (fabs(last - ret) > EXP);

	return ret;
}

  主函数:

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:Mysqrt.c
* 功能:求一个数字的平方根
*
* 当前版本:V1.0
* 作者:sustzc
* 完成日期:2018年4月3日19:09:38
*/

# include <stdio.h>
# include <math.h>
# include <assert.h>

# define EXP 0.00000000000000000000000001

int main(void)
{
	double n = 0.0;

	printf("请输入数字:");
	scanf("%lf", &n);
	printf("%lf的平方根是%lf\n", n, MySqrt(n));

	return 0;
}

  输出结果:

【C】库函数之sqrt

相关标签: C库函数 sqrt