Numerical Calculation 数值计算
数值计算第一次实验(C语言版)
C语言编程常用数值计算的高性能实现
/* 高位全0,低N位全1 */
#define Low_N_Bits_One(N) ((1<<N) -1)/* 高位全1,低N位全0 */
#define Low_N_Bits_Zero(N) (~((1<<N) -1))/* 低位第N位置1 */
#define Set_Bit_N(NUM, N) (NUM | (1 << (N - 1)))/* 低位第N位置0 */
#define Clear_Bit_N(NUM, N) (NUM & (~(1 << (N - 1))))/* 低位第N位反转 */
#define Reverse_Bit_N(NUM, N) ((NUM) ^ (1 << (N - 1)))/* 上取整 */
#define UpRoun8(Num) (((Num) + 0x7) & (~0x7))
#define UpRoun16(Num) (((Num) + 0xf) & (~0xf))
#define UpRoun32(Num) (((Num) + 0x1f) & (~0x1f))/* 下取整 */
#define LowRoun8(Num) ((Num) & (~0x7))
#define LowRoun16(Num) ((Num) & (~0xf))
#define LowRoun32(Num) ((Num) & (~0x1f))/* 求商 */
#define Div8(Num) ((Num)>>3)
#define Div16(Num) ((Num)>>4)
#define Div32(Num) ((Num)>>5)/* 余数进位求商 */
#define UpDiv8(Num) (((Num)>>3) + !!((Num) & 0x7))
#define UpDiv16(Num) (((Num)>>4) + !!((Num) & 0xf))
#define UpDiv32(Num) (((Num)>>5) + !!((Num) & 0x1f))/* 求余 */
#define M8(Num) ((Num) & 0x7)
#define M16(Num) ((Num) & 0xf)
#define M32(Num) ((Num) & 0x1f)/* 求反余
即求最小的x,满足(Num + x) % 模数 == 0
例如 RM16(Num) 等价于 (16 - Num%16) % 16 */
#define RM8(Num) ((~(Num) + 1) & 0x7)
#define RM16(Num) ((~(Num) + 1) & 0xf)
#define RM32(Num) ((~(Num) + 1) & 0x1f)
线性方程组求解
1. 二分法方程求根
2. 顺序消元法解线性方程组
3. 列选主元消去法解线性方程组
4. 全选主元消去法解线性方程组
5. Doolittle(杜立特尔)分解
6. Crout(克洛特)分解解线性方程组
7. 平方根法法解线性方程组
8. 拉格朗日插值法
9. 牛顿插值法
10. Hermite插值法
11. 最小二乘法(线性拟合)
12. 变步长梯形求积法计算定积分
13. Romberg算法
14. 改进欧拉法
main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "head.h"// 这些函数 的实现在 head.h头文件中
double f(double); //方 程f(x)=0的函数
double f2(double); //变步长积分函数
void Dodichotomy(); //二分法
void Doleastsquares(); //最小二乘法
void Doshunxu(); //顺序消元法
void Doliezhu(); //列主消元法
void Doquanxuan(); //全选主元消去
void Dodoolittle(); //杜利特尔分解法
void Docrout(); //Crout(克洛特)分解解线性方程组
void Dopingfang(); //平方根法解线性方程组
void Dolagrange(); //拉格朗日插值法
void Donewton(); //牛顿插值法
void Dohermite(); //Hermite插值法
void Doleastsquares(); //最小二乘法
void Dochangestep(); //变步长梯形求积法计算定积分
void Doromberg(); //龙贝格算法
void Doeuler(); //改进欧拉算法int main()
{char ch;int n;for(;;){n = Menu();switch(n){case 1:Dodichotomy();break;case 2:Doshunxu();break;case 3:Doliezhu();break;case 4:Doquanxuan();break;case 5:Dodoolittle();break;case 6:Docrout();break;case 7:Dopingfang();break;case 8:Dolagrange();break;case 9:Donewton();break;case 10:Dohermite();break;case 11:Doleastsquares();break;case 12:Dochangestep();break;case 13:Doromberg();break;case 14:Doeuler();break;case 15:return 0;default:printf("输入错误,请重新输入\n");break;}}
}void Dodichotomy()
{printf("%lf\n",Dichotomy(f,-4,4,1e-5));
}void Doleastsquares()
{double x[5] = {1,2,3,4,5};double y[5] = {0,2,2,5,4};double a,b;LeastSquares(x,y,5,&a,&b);printf("a = %lf;b = %lf\n",a,b);
}double f(double x)
{double y;y = x*(x*(2.0*x-4.0)+3.0)-6.0;return y;
}void Doshunxu()
{double a[3][3]={2.5,2.3,-5.1,5.3,9.6,1.5,8.1,1.7,-4.3};double b[3] = {3.7,3.8,5.5};Shunxu(a,3,3,b);
}void Doliezhu()
{double a[3][3]={2.5,2.3,-5.1,5.3,9.6,1.5,8.1,1.7,-4.3};double b[3] = {3.7,3.8,5.5};Liezhu(a,3,3,b);
}void Doquanxuan()
{double a[3][3]={2.5,2.3,-5.1,5.3,9.6,1.5,8.1,1.7,-4.3};double b[3] = {3.7,3.8,5.5};Quanxuan(a,3,3,b);
}void Dodoolittle()
{float a[3][3] = {1,-1,3,2,-4,6,4,-9,2};float b[4] = {1,4,1};Doolittle(a,3,3,b);
}void Docrout()
{float a[3][3] = {1,-1,3,2,-4,6,4,-9,2};float b[4] = {1,4,1};Crout(a,3,3,b);
}void Dopingfang()
{int i;double a[4][4] = {{1,2,1,-3},{2,5,0,-5},{1,0,14,1},{-3,-5,1,15}};double b[4] = {1,2,16,8};double d[4] = {0};double x[4] = {0};double y[4] = {0};double L[4][4] = {0};Cholesky(a,b,L,d,x,y,4);printf("方程的解为:\n");for(i=1;i<=4;i++)printf("x(%d)=%f\n",i,x[i-1]);
}void Dolagrange()
{Point points[20] = {{0.56160,0.82741},{0.56280,0.82659},{0.56401,0.82577},{0.56521,0.82495}};Lagrange(points,4,0.5635);
}void Donewton()
{double b[6][7] = {{0.4,0.41075},{0.55,0.57815},{0.65,0.69675},{0.80,0.88811},{0.90,1.02652},{1.05,1.25382}};Newton(b,6,0.596);
}void Dohermite()
{static double xi[3] = {0.1,0.3,0.5};static double yi[3] = {0.099833,0.295520,0.479426};static double dyi[3] = {0.995004,0.955336,0.877583};Hermite(0.4,xi,yi,dyi,3,1.0e-12);
}double f2(double x)
{double sum;if(x = 0) return 1;sum = sin(x)/x;return sum;
}void Dochangestep()
{Changestep(f2,1,2,0.0000001);
}double f3(double x,double y)
{return -y + x + 1;
}void Doromberg()
{Romberg(f2,0,1,0.0000001);
}void Doeuler()
{Euler(f3,0,0.5,1,5);
}
head.h
/*
* 输入点结构
*/
typedef struct stPoint
{double x;double y;
}Point;/*
* 开始菜单
*/
int Menu()
{int n;printf("----------------数值实验------------------\n");printf("| |\n");printf("| [1]:二分法方程求根 |\n");printf("| [2]:顺序消元法解线性方程组 |\n");printf("| [3]:列选主元消去法解线性方程组 |\n");printf("| [4]:全选主元消去法解线性方程组 |\n");printf("| [5]:Doolittle(杜立特尔)分解 |\n");printf("| [6]:Crout(克洛特)分解解线性方程组 |\n");printf("| [7]:平方根法法解线性方程组 |\n");printf("| [8]:拉格朗日插值法 |\n");printf("| [9]:牛顿插值法 |\n");printf("| [10]:Hermite插值法 |\n");printf("| [11]:最小二乘法(线性拟合) |\n");printf("| [12]:变步长梯形求积法计算定积分 |\n");printf("| [13]:Romberg算法 |\n");printf("| [14]:改进欧拉法 |\n");printf("| [15]:退出 |\n");printf("| |\n");printf("------------------------------------------\n");printf("请输入你要选择的操作:");scanf("%d",&n);return n;
}/*
* 二分法方程求根
* fun: 求方程fun(x) = 0的函数fun(x)
* left: 根区间左边点
* right: 根区间右边点
* eps: 二分法的精度
*/
double Dichotomy(double (*fun)(double),double left,double right,double eps)
{double yleft,yright,ym;double middle;do{yleft = fun(left);yright = fun(right);middle = (left + right)/2;ym = fun(middle);if(ym*yleft < 0){right = middle;}else{left = middle;}}while(fabs(ym) >= eps);return left;
}/*
* 高斯顺序消元法
* a[][]:系数矩阵
* n,m:系数矩阵的维数
* b[]:常数矩阵
*/
void Shunxu(double (*a)[3],int n,int m,double b[])
{int i,j,t,tmp;double x[20];//下面高斯顺序消元for(i = 0 ; i < n ; i++)//将矩阵化成上三角矩阵for(j = i+1 ; j < m ; j++){tmp = a[j][i]/a[i][i];for(t = i+1 ; t < m; t++)a[j][t] = a[j][t] - tmp*a[i][t];b[j] = b[j] - tmp*b[i];a[j][i] = 0;}//回代x[n-1] = b[n-1]/a[n-1][n-1];for(i = n-2 ; i >= 0 ; i--){x[i] = b[i];for(j = i+1 ; j < m ; j++)x[i] -= a[i][j]*x[j];x[i]/=a[i][i];}//输出结果printf("结果为:\n");for(i = 0 ; i < n ; i++)printf("x[%d] = %lf\n",i+1,x[i]);
}/*
* 获取主元所在的行
* a[][]: 系数矩阵
* n: 系数矩阵的维数
* k: 所在的列
*/
int getMaxzhu(double (*a)[3],int n,int k)
{int i;int laber = k;double maxlaber = 0;for(i = k ; i < n ; i++)if(maxlaber < fabs(a[i][k])){maxlaber = fabs(a[i][k]);laber = i;}return laber;
}/*
* 高斯列主消元法
* a[][]:系数矩阵
* n,m:系数矩阵的维数
* b[]:常数矩阵
*/
void Liezhu(double (*a)[3],int n,int m,double b[])
{int i,j,t,tmp,laber;double x[20];//高斯消元法for(i = 0 ; i < n ; i++){laber = getMaxzhu(a,3,i);if(laber != i){for(j = 0 ; j < m ; j++){tmp = a[i][j];a[i][j] = a[laber][j];a[laber][j] = tmp;}tmp = b[laber];b[laber] = b[i];b[i] = tmp;}//消元for(j = i+1 ; j < m ; j++){tmp = a[j][i]/a[i][i];for(t = i+1 ; t < m; t++)a[j][t] = a[j][t] - tmp*a[i][t];b[j] = b[j] - tmp*b[i];a[j][i] = 0;}}//回代x[n-1] = b[n-1]/a[n-1][n-1];for(i = n-2 ; i >= 0 ; i--){x[i] = b[i];for(j = i+1 ; j < m ; j++)x[i] -= a[i][j]*x[j];x[i]/=a[i][i];}//输出结果printf("结果为:\n");for(i = 0 ; i < n ; i++)printf("x[%d] = %lf\n",i+1,x[i]);
}/*
* 根据L和U的矩阵求解方程组的解
* l[][20]: 矩阵L u[][20]: 矩阵U
* b[]: 常数矩阵
* x[]: 解的矩阵
* n: 维数
*/
void solve(float l[][20],float u[][20],float b[],float x[],int n)
{int i,j;float t,s1,s2;float y[20];//第一次回带过程for(i = 0 ; i < n ; i++){s1 = 0 ; for(j = 0 ; j < i-1 ; j++){t = -l[i][j];s1 = s1 + t*y[j];}y[i] = (b[i] + s1)/l[i][i];}for(i = n-1 ; i >= 0 ; i--){s2 = 0;for(j = n-1 ; j > i-1 ; j--){t = -u[i][j];s2 = s2 + t*x[j];}x[i] = (y[i] + s2)/u[i][i];}
}/*
* 高斯全选主元消元法
* a[][]:系数矩阵
* n,m:系数矩阵的维数
* b[]:常数矩阵
*/
void Quanxuan(double (*a)[3],int n,int m,double b[])
{int i,j,t,p,tmp,max,w = 0,y = 0;double x[20];for(i = 0 ; i < n ; i++){for(p = i ; p < m ; p++){max = getMaxzhu(a,3,p);if(a[w][y] < a[max][p]){w = max;y = p;}}for(j = 0 ; j < m ; j++){tmp = a[i][j];a[i][j] = a[w][j];a[w][j] = tmp;}for(j = i ; j < n; j++){tmp = a[j][i];a[j][i] = a[i][y];a[i][y] = tmp;}//消元for(j = i+1 ; j < m ; j++){tmp = a[j][i]/a[i][i];for(t = i+1 ; t < m; t++)a[j][t] = a[j][t] - tmp*a[i][t];b[j] = b[j] - tmp*b[i];a[j][i] = 0;}}//回代x[n-1] = b[n-1]/a[n-1][n-1];for(i = n-2 ; i >= 0 ; i--){x[i] = b[i];for(j = i+1 ; j < m ; j++)x[i] -= a[i][j]*x[j];x[i]/=a[i][i];}//输出结果printf("结果为:\n");for(i = 0 ; i < n ; i++)printf("x[%d] = %lf\n",i+1,x[i]);
}/*
* Doolittle(杜利特尔分解法)
* (*a)[4]: 系数矩阵a
* int m,n: 矩阵a的维数
* b[]: 矩阵b
*/
void Doolittle(float (*a)[3],int n,int m,float b[])
{float l[20][20],u[20][20],x[20];int i,j,k;float s1,s2;// 将所有的数组置零,同时将L矩阵的对角值设为1 for(i = 0 ; i < 20 ; i++)for(j = 0 ; j < 20 ; j++ ){l[i][j] = 0;u[i][j] = 0;if(j == i) l[i][j] = 1;}// 下面求解矩阵L和Ufor(i = 0 ; i < n ; i++){for(j = i ; j <= n ; j++){s1 = 0;for(k = 0 ; k < i-1 ; k++)s1 = s1 + l[i][k]*u[k][j];u[i][j] = a[i][j] - s1;}for(j = i+1; j < n ;j++){s2 = 0; for(k = 0 ; k < i-1 ; k++)s2 = s2 + l[j][k]*u[k][i];l[j][i] = (a[j][i] - s2)/u[i][i];}}printf("array L:\n");/*输出矩阵L*/for(i = 0;i < n;i++){for(j = 0;j < n;j++)printf("%7.3f ",l[i][j]);printf("\n");}printf("array U:\n");/*输出矩阵U*/for(i = 0;i < n;i++){for(j = 0;j < n;j++)printf("%7.3f ",u[i][j]); printf("\n");}solve(l,u,b,x,n);printf("解为:\n");for(i = 0 ; i < n ; i++){printf("x%d = %f\n",i,x[i]);}
}/*
* (*a)[3]: 系数矩阵a
* int n,m: 矩阵a的维数
* b[]: 常数矩阵
*/
void Crout(float (*a)[3],int n,int m,float b[])
{int i,j,k;float l[20][20],u[20][20];float x[20],y[20];// 将所有的数组置零,同时将U矩阵的对角值设为1 for(i = 0 ; i < 20 ; i++)for(j = 0 ; j < 20 ; j++ ){l[i][j] = 0;u[i][j] = 0;if(j == i) u[i][j] = 1;}l[0][0]=a[0][0];for(i = 0 ; i < n ; i++){l[i][0]=a[i][0];//计算第一行的l[][]u[0][i]=a[0][i]/l[0][0];//计算第一列的u[][]}for(i = 0 ; i < n - 1 ; i++){for(j = 0 ; j <= i ; j++)//计算第2行到第size-1行的l[][]{l[i][j] = a[i][j];for(k = 0 ; k < j ; k++){l[i][j] = l[i][j] - l[i][k]*u[k][j];}}printf("\n");for(j = i ; j < n ; j++)//计算第2行到第size行的u[][]{u[i][j] = a[i][j];for(k = 0 ; k <= i-1 ; k++){u[i][j] = u[i][j] - l[i][k]*u[k][j];}u[i][j] = u[i][j]/l[i][i];}printf("\n");}for(j = 0;j < n;j++)//计算第n行的l[][]{l[n-1][j]=a[n-1][j];for(k=0;k<=j-1;k++){l[n-1][j]=l[n-1][j]-l[n-1][k]*u[k][j];}}printf("\n");printf("array L:\n");/*输出矩阵L*/for(i = 0;i < n;i++){for(j = 0;j < n;j++)printf("%7.3f ",l[i][j]);printf("\n");}printf("array U:\n");/*输出矩阵U*/for(i = 0;i < n;i++){for(j = 0;j < n;j++)printf("%7.3f ",u[i][j]); printf("\n");}solve(l,u,b,x,n);printf("解为:\n");for(i = 0 ; i < n ; i++){printf("x%d = %f\n",i,x[i]);}
}/*
* 平方根法法解线性方程组
* a[][],b[]: 系数矩阵
* n: 矩阵的维数
* Cholesky():算法函数
*/
void Cholesky(double a[][4],double b[],double L[][4],double d[],double x[],double y[],int n)
{int i,j,k;double s;for(i=0;i<n;i++)L[i][i]=1;d[0]=a[0][0];for(i=1;i<n;i++){for(j=0;j<i;j++){s=0;for(k=0;k<j;k++)s=s+L[i][k]*d[k]*L[j][k];L[i][j]=(a[i][j]-s)/d[j];}s=0;for(k=0;k<i;k++)s=s+L[i][k]*L[i][k]*d[k];d[i]=a[i][i]-s;}y[0]=b[0];for(i=1;i<n;i++){s=0;for(k=0;k<i;k++)s=s+L[i][k]*y[k];y[i]=b[i]-s;}x[n-1]=y[n-1]/d[n-1];for(i=n-2;i>=0;i--){s=0;for(k=i+1;k<n;k++)s=s+L[k][i]*x[k];x[i]=y[i]/d[i]-s;}for(i=1;i<=n;i++)printf("d(%d)=%f\n",i,d[i-1]);printf("矩阵L为:\n");for(i=0;i<n;i++){for(j=0;j<=i;j++)printf("%f ",L[i][j]);printf("\n");}
}/*
* Point *point: 插值节点结构体指针
* int n: 插值点的个数
* double s: 待求插值点
*/
void Lagrange(Point *points,int n,double x)
{int i,j;double tmp,lagrange = 0;/* tmp:拉格朗日基函数,lagrange:根据拉格朗日函数得出的f(x) *///利用拉格朗日插值公式计算函数x的值for(i = 0 ; i <= n ; i++){for(j = 0 , tmp = 1 ; j <= n ; j++){if(j == i) // 去掉xi与xj相等的情况continue; //范德蒙行列式下标就是j!=k,相等分母就没有意义了tmp = tmp*(x - points[j].x)/(points[i].x-points[j].x); //拉格朗日基函数lagrange=lagrange+tmp*points[i].y; //最后计算基函数*y,全部加起来,就是该x项的拉格朗日函数了}}//拉格朗日函数计算完毕,代入所求函数x的值,求解就ok了printf("\n拉格朗日函数f(%lf)=%lf\n",x,lagrange);
}/*
* 最小二乘法
* x[],y[]: 观测点数据
* n: 观测点数量
* a,b: y = ax + b,线性拟合的两个系数
*/
void LeastSquares(double x[],double y[],int n,double *a,double *b)
{int i;double sumx = 0,sumy = 0,sumxx = 0,sumxy = 0;for(i = 0 ; i < n ; i++){sumx += x[i];sumy += y[i];sumxx += x[i]*x[i];sumxy += x[i]*y[i];}// n*a + sumx*b = sumy;// sumx*a + sumxx*b = sumxy;*b = (sumy*sumx - sumxy*n)/(sumx*sumx - sumxx*n);*a = (sumy - sumx*(*b))/n;
}/*
* 牛顿插值法
* b[][]: 均差表
* n: 插值点的个数
* x: 待求插值点
*/
void Newton(double (*b)[7],int n,double x)
{double sum = 0,w = 1,cc[2][4];// sum:保存牛顿插值多项式int i,j,k,m,z = 0;// 求均差表for(i = 2 , k = 1; i < 7;i++,k++){for(j = i - 1 ; j < n ; j++){b[j][i] = (b[j-1][j-1] - b[j][i - 1])/(b[j - k][0] - b[j][0]);}}for(m = 0 ; m < 4 ; m++,z = 0){cc[0][m] = b[m+1][m+2];do{w *= (x - b[z][0]);}while(z++ != m);cc[1][m] = w;}sum = b[0][1];for(m = 0 ; m < 4 ; m++)sum += (cc[0][m]*cc[1][m]);printf("\n插值y为:%lf\n",sum);
}void Hermite(double x,double xi[],double yi[],double dyi[],int N,double EPS)
{int i,j;double li,sum,y,gix[N],hix[N];for(i = 0 ; i < N ; i++){li = 1.0; sum = 0.0;for(j = 0 ; j < N ; j++){if(j != i){li *= (x - xi[j])/(xi[i] - xi[j]);sum += 1.0/(xi[i] - xi[j]);}li = li*li;gix[i] = (1.0 - 2.0*(x - xi[i])*sum)*li;hix[i] = (x - xi[i])*li;}y = 0.0;for(i = 0; i < N; i++)y += yi[i] * gix[i] + dyi[i] * hix[i];printf("x = %15.6e p(x) = %15.8e\n",x,y);}
}/*
* 变步长梯形求积法计算定积分
* 原理: 利用若干个小梯形面积代替原方程的积分
* fun(): 积分函数
* a,b: 积分上下限
* eps: 误差
*/
void Changestep(double (*fun)(double),double a,double b,double eps)
{int i,n; // i为分段变步长的数量double fa,fb,h,t1,p,s,x,t;// fa,fb: 代表边界值带入函数后的值// h: 分段后每个子区间的长度// x: 分段后的分段点// p: 为当前误差fa = fun(a);fb = fun(b);n = 1;h = b - a;t1 = h*(fa + fb)/2;p = eps + 1;while(p >= eps){s = 0;for(i = 0 ; i <= n-1 ; i++){x = a + (i + 0.5)*h;s += fun(x);}t = t1/2 + h*s/2; //根据公式计算p = fabs(t1 - t);printf("步长为%d时的Tn = %lf\tT2n = %lf\t,误差变化为:%lf\n",n,t1,t,p);t1 = t;n = n*2;h = h/2;}printf("经过变长梯形求积法得到的方程的结果为:%lf\n",t);
}/*
* Romberg算法
* fun(): 积分函数
* a,b: 积分上下限
* eps: 误差限
*/
void Romberg(double (*f)(double),double a,double b,double eps)
{double h,T1,T2,S,S1,S2,C1,C2,R1,R2,z[100][4];//h:分段后每个子区间的长度int i,j,k = 1;h = b-a;T1 = (f(a) + f(b))*h/2;z[0][0] = T1;while(1){S = 0;double x;for(x = a + h/2; x < b ; x = x+h)S += f(x);T2 = (T1 + h*S)/2;z[k][0] = T2;S2 = T2 + (T2 - T1)/3; // 利用T1,T2计算S2z[k][1] = S2;if(k == 1);else{C2 = S2 + (S2 - S1)/15; // 利用S1,S2计算C2z[k][2] = C2;if(k == 2);else{R2 = C2 + (C2 - C1)/63; //利用C1,C2计算R2z[k][3] = R2;if(k == 3);else{if(fabs(R2 - R1) < eps);break;}R1 = R2;}C1 = C2;}k++;h /= 2;T1 = T2;S1 = S2;}printf("%3c%6c%12c%12c%12c\n",'k','T','S','C','R');for(i = 0; i < k;i++){printf("%3d",i);if(i < 3){for(j = 0 ; j <= i ; j++){printf("%12.7lf",z[i][j]);}printf("\n");}else{for(j = 0;j < 4 ; j++){printf("%12.7lf",z[i][j]);}printf("\n");}}
}/*
* 改进的欧拉算法
* f(): 积分函数
* a,b: 积分上下限
* y0: 初值
* n: 将区间等分的数目
*/
void Euler(double (*f)(double, double),double a,double b,double y0,int n)
{double h;double x,y,xn,yn,yp;int i;h = (b - a)/n;x = a;y = y0;for(i = 1 ; i <= n ; i++){xn = x + h;yn = y + h*f(x,y);yp = yn + h/2*(f(x,y) + f(xn,yn));printf("x%d = %lf,y%d = %lf\n",i,xn,i,yp);x = xn;y = yp;}}
编译
gcc.sh
#!/bin/bash# File Name : gccfile.sh
# Author : xiaorui
# Created Time :2017年05月01日 星期一 16时47分31秒
# Program Funtion :gcc Filegcc main.c -lm -o main
# -lm: 链接相应的数学库函数