数学库(math.h)

作者:追风剑情 发布于:2020-3-18 19:58 分类:C

ANSI C标准的一些数学函数
原型 描述
double acos(double x) 返回余弦值为x的角度(0~π弧度)
double asin(double x) 返回正弦值为x的角度(-π/2~π/2弧度
double atan(double x) 返回正切值为x的角度(-π/2~π/2弧度
double atan2(doubley, double x) 返回正切值为y/x的角度(-π~π弧度
double cos(double x) 返回x的余弦值,x的单位为弧度
double sin(double x) 返回x的正弦值,x的单位为弧度
double tan(double x) 返回x的正切值,x的单位为弧度
double exp(double x) 返回x的指数函数的值(ex
double log(double x) 返回x的自然对数值
double log10(double x) 返回x的以10为底的对数值
double pow(double x, double y) 返回x的y次幂
double sqrt(double x) 返回x的平方根
double cbrt(double x) 返回x的立方值
double ceil(double x) 返回不小于x的最小整数值
double fabs(double x) 返回x的绝对值
double floor(double x) 返回不大于x的最大整数值

      C标准专门为float类型和long double类型提供了标准函数,即在原函数名前加上f或l前缀。因此,sqrtf()是sqrt()的float版本,sqrtl()是sqrt()的long double版本。可以利用C11新增的泛型选择表达式定义一个泛型宏,根据参数类型选择最合适的数学函数版本。

tgmath.h库(C99)

      C99标准提供的tgmath.h头文件中定义了泛型类型宏。如果在math.h中为一个函数定义了3种类型(float、double和long double)的版本,那么tgmath.h文件就创建一个泛型类型宏,与原来double版本的函数名同名。如果编译器支持复数运算,就会支持complex.h头文件,其中声明了复数运算相关的函数。例如,声明有csqrtf()、csqrt()和csqrtl(),这些函数分别返回float complex、double complex和long double complex类型的复数平方根。如果提供这些支持,那么tgmath.h中的sqrt()宏也能展开为相应的复数平方根函数。如果包含了tgmath.h,要调用sqrt()函数而不是sqrt()宏,可以用圆括号把被调用的函数名括起来:sqrt(x) 为调用宏,(sqrt)(x)或(*sqrt)(x)为调用函数。 

示例:三角问题

//Visual Studio中加上这句才可以使用scanf()
//否则只能使用scanf_s()
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//malloc()、free()
#include <stdlib.h>
#include <time.h>
#include <math.h>

//PI的值通过计算表达式4*atan(1)得到
#define RAD_TO_DEG (180/(4*atan(1)))

typedef struct polar_v {
	double magnitude;
	double angle;
} Polar_V;

typedef struct rect_v {
	double x;
	double y;
} Rect_V;

Polar_V rect_to_polar(Rect_V);

//argc: 参数个数 argv[]: 参数数组
//int main(int argc, char **argv)
int main(int argc, char *argv[])
{
	Rect_V input;
	Polar_V result;

	puts("Enter x and y coordinates; enter q to quit:");
	while (scanf("%lf %lf", &input.x, &input.y) == 2)
	{
		result = rect_to_polar(input);
		printf("magnitude = %0.2f, angle = %0.2f\n",
			result.magnitude, result.angle);
	}
	puts("Bye.");

	system("pause");
	return 0;
}

Polar_V rect_to_polar(Rect_V rv)
{
	Polar_V pv;

	pv.magnitude = sqrt(rv.x * rv.x + rv.y * rv.y);
	if (pv.magnitude == 0)
		pv.angle = 0.0;
	else
		pv.angle = RAD_TO_DEG * atan2(rv.y, rv.x);
	return pv;
}

运行测试
111.png

示例:利用泛型选择表达式选择合适的函数版本

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> //C99特性
#include <string.h>
#include <math.h>
#include <ctype.h>

#define RAD_TO_DEG (180/(4*atanl(1)))

// 泛型平方根函数
#define SQRT(X) _Generic((X),\
	long double: sqrtl,\
	default: sqrt,\
	float: sqrtf)(X)

// 泛型正弦函数,角度的单位为度
#define SIN(X) _Generic((X),\
	long double: sinl((X)/RAD_TO_DEG),\
	default: sin((X)/RAD_TO_DEG),\
	float: sinf((X)/RAD_TO_DEG)\
)

int main(int argc, char* argv[])
{
	float x = 45.0f;
	double xx = 45.0;
	long double xxx = 45.0L;

	long double y = SQRT(x);
	long double yy = SQRT(xx);
	long double yyy = SQRT(xxx);

	printf("%.17Lf\n", y);  // 匹配 float
	printf("%.17Lf\n", yy); // 匹配 default
	printf("%.17Lf\n", yyy); // 匹配 long double

	int i = 45;
	yy = SQRT(i); // 匹配 default
	printf("%.17Lf\n", yy);
	yyy = SIN(xxx); // 匹配 long double
	printf("%.17Lf\n", yyy);

	system("pause");
	return 0;
}


标签: C语言

Powered by emlog  蜀ICP备18021003号   sitemap

川公网安备 51019002001593号