比如说,sqr2要精确到小数点后100位,用C语言怎么编写程序啊?
10 个解决方案
#1
首先开方运算必须采用迭代法,至于精确到100位,必须编写专门的程序,c语言提供的基本数据类型无法直接给出.
#2
用迭代法求a的平方根
Xn+1=1/2*(Xn+a/Xn)
取Xo=a/2
Xn+1=1/2*(Xn+a/Xn)
取Xo=a/2
#3
网上有例程,下一个看看。你可以用一个整型数组存储结果。
#4
用二分法可以编写一个速度不是很快的程序
其中用数组保存计算结果
编写要比用迭代公式Xn+1=1/2*(Xn+a/Xn)简单的多
因为不用除法
速度慢些
但计算100位足够了
其中用数组保存计算结果
编写要比用迭代公式Xn+1=1/2*(Xn+a/Xn)简单的多
因为不用除法
速度慢些
但计算100位足够了
#5
用级数展开
#6
用泰勒公式展开为级数即可。
#7
迭代法速度最快
#8
用快速截弦法比较好.只有-和*的运算.
以下是转自colacoca兄的话:
牛顿法突出优点是收敛的速度快。但它有个明显的缺点:需要计算导数f'(x),如果函数f(x)比较复杂,使用牛顿法是不方便的。
为了避开导数计算,就用差商:
(f(Xk)-f(X0))/(Xk-X0)
......
用以替换牛顿公式中得导数f'(Xk)
最后得
Xk+1=Xk-f(Xk)*(Xk-X0)/(f(Xk)-f(X0))
求得的Xk+1其实就是弦线与X轴的交点,所以上面的算法称弦截法
然后又是一阵推导.....
......
最后,为了加快收敛速度,改用差商
(f(Xk)-f(Xk-1))/(Xk-Xk-1)
得出快速弦截法的公式:
Xk+1=Xk-f(Xk)*(Xk-Xk-1)/(f(Xk)-f(Xk-1))
注:上面的Xk,Xk+1,Xk-1中的k,k-1,k+1都是X的下标,不是变量Xk减去1的意思
所以才有我的
x1=x0;
x0=x;
x=x0-(x0-x1)*(x0^2-A)/((x0^2-A)-(x1^2-A));
这3个式子
以下是转自colacoca兄的话:
牛顿法突出优点是收敛的速度快。但它有个明显的缺点:需要计算导数f'(x),如果函数f(x)比较复杂,使用牛顿法是不方便的。
为了避开导数计算,就用差商:
(f(Xk)-f(X0))/(Xk-X0)
......
用以替换牛顿公式中得导数f'(Xk)
最后得
Xk+1=Xk-f(Xk)*(Xk-X0)/(f(Xk)-f(X0))
求得的Xk+1其实就是弦线与X轴的交点,所以上面的算法称弦截法
然后又是一阵推导.....
......
最后,为了加快收敛速度,改用差商
(f(Xk)-f(Xk-1))/(Xk-Xk-1)
得出快速弦截法的公式:
Xk+1=Xk-f(Xk)*(Xk-Xk-1)/(f(Xk)-f(Xk-1))
注:上面的Xk,Xk+1,Xk-1中的k,k-1,k+1都是X的下标,不是变量Xk减去1的意思
所以才有我的
x1=x0;
x0=x;
x=x0-(x0-x1)*(x0^2-A)/((x0^2-A)-(x1^2-A));
这3个式子
#9
我用Borland C++ 3.1编写了一个算法,main调用sqrt计算2的算术平方根。更通用的算法只要更改一下main即可。这里的算法已经把原理解释的足够清楚。
本程序中,常数W表示数据的总位数,D标是小数部分位数。
#include <stdio.h>
#include <string.h>
const W=101;
const D=100;
int pos(int power){
return power+D;
}
int power(int pos){
return pos-D;
}
void fill(int d[W],int t){
for (int i=0;i<W;i++) d[i]=t;
}
void copy(int x[W],int y[W]){
for (int i=0;i<W;i++) y[i]=x[i];
}
void assign(int x[W],char* n, char* d){
fill(x,0);
char *p;
p=n;
int L=strlen(n);
int i;
for (i=L-1;i>=0;i--,p++) x[pos(i)]=*p-'0';
L=strlen(d);
p=d;
for (i=-1;i>=-L;i--,p++) x[pos(i)]=*p-'0';
}
int equal(int x[W],int y[W]){
for (int i=W-1;i>0;i--)
if (x[i]!=y[i]) return 0;
return 1;
}
void mid(int x[W],int y[W],int z[W]){
z[0]=x[0]+y[0];
for (int i=1;i<W;i++){
z[i]=x[i]+y[i]+z[i-1]/10;
z[i-1]=z[i-1]%10;
}
for (i=W-1;i>0;i--) {
z[i-1]+=(z[i]*10)%20;
z[i]/=2;
}
z[0]/=2;
}
void sqr(int x[W], int y[W]){
fill(y,0);
for (int i=0;i<W;i++){
for (int j=0;j<W;j++){
int t=pos(power(i)+power(j));
if ((t>=0)&&(t<W)) y[t]+=x[i]*x[j];
}
}
for (i=0;i<W-1;i++){
y[i+1]+=y[i]/10;
y[i]=y[i]%10;
}
y[W-1]=y[W-1]%10;
}
int compare(int x[W],int y[W]){
for (int i=W-1;i>=0;i--){
if (x[i]<y[i]) return -1;
if (x[i]>y[i]) return 1;
}
return 0;
}
void print(int x[W]){
int i;
for (i=W-1;i>=0;i--){
printf("%c",'0'+x[i]);
if (i==D) printf(".");
}
printf("\n");
}
void sqrt(int x[W],int y[W]){
int a[W],b[W],c[W];
fill(a,0);
copy(x,b);
b[pos(0)]++;
while (!equal(a,b)) {
mid(a,b,c);
sqr(c,y);
if (compare(y,x)<0) copy(c,a);
else copy(c,b);
}
copy(c,y);
return;
}
void main(){
int x[W],y[W];
assign(x,"2","0");
sqrt(x,y);
print(y);
}
本程序中,常数W表示数据的总位数,D标是小数部分位数。
#include <stdio.h>
#include <string.h>
const W=101;
const D=100;
int pos(int power){
return power+D;
}
int power(int pos){
return pos-D;
}
void fill(int d[W],int t){
for (int i=0;i<W;i++) d[i]=t;
}
void copy(int x[W],int y[W]){
for (int i=0;i<W;i++) y[i]=x[i];
}
void assign(int x[W],char* n, char* d){
fill(x,0);
char *p;
p=n;
int L=strlen(n);
int i;
for (i=L-1;i>=0;i--,p++) x[pos(i)]=*p-'0';
L=strlen(d);
p=d;
for (i=-1;i>=-L;i--,p++) x[pos(i)]=*p-'0';
}
int equal(int x[W],int y[W]){
for (int i=W-1;i>0;i--)
if (x[i]!=y[i]) return 0;
return 1;
}
void mid(int x[W],int y[W],int z[W]){
z[0]=x[0]+y[0];
for (int i=1;i<W;i++){
z[i]=x[i]+y[i]+z[i-1]/10;
z[i-1]=z[i-1]%10;
}
for (i=W-1;i>0;i--) {
z[i-1]+=(z[i]*10)%20;
z[i]/=2;
}
z[0]/=2;
}
void sqr(int x[W], int y[W]){
fill(y,0);
for (int i=0;i<W;i++){
for (int j=0;j<W;j++){
int t=pos(power(i)+power(j));
if ((t>=0)&&(t<W)) y[t]+=x[i]*x[j];
}
}
for (i=0;i<W-1;i++){
y[i+1]+=y[i]/10;
y[i]=y[i]%10;
}
y[W-1]=y[W-1]%10;
}
int compare(int x[W],int y[W]){
for (int i=W-1;i>=0;i--){
if (x[i]<y[i]) return -1;
if (x[i]>y[i]) return 1;
}
return 0;
}
void print(int x[W]){
int i;
for (i=W-1;i>=0;i--){
printf("%c",'0'+x[i]);
if (i==D) printf(".");
}
printf("\n");
}
void sqrt(int x[W],int y[W]){
int a[W],b[W],c[W];
fill(a,0);
copy(x,b);
b[pos(0)]++;
while (!equal(a,b)) {
mid(a,b,c);
sqr(c,y);
if (compare(y,x)<0) copy(c,a);
else copy(c,b);
}
copy(c,y);
return;
}
void main(){
int x[W],y[W];
assign(x,"2","0");
sqrt(x,y);
print(y);
}
#10
up
#1
首先开方运算必须采用迭代法,至于精确到100位,必须编写专门的程序,c语言提供的基本数据类型无法直接给出.
#2
用迭代法求a的平方根
Xn+1=1/2*(Xn+a/Xn)
取Xo=a/2
Xn+1=1/2*(Xn+a/Xn)
取Xo=a/2
#3
网上有例程,下一个看看。你可以用一个整型数组存储结果。
#4
用二分法可以编写一个速度不是很快的程序
其中用数组保存计算结果
编写要比用迭代公式Xn+1=1/2*(Xn+a/Xn)简单的多
因为不用除法
速度慢些
但计算100位足够了
其中用数组保存计算结果
编写要比用迭代公式Xn+1=1/2*(Xn+a/Xn)简单的多
因为不用除法
速度慢些
但计算100位足够了
#5
用级数展开
#6
用泰勒公式展开为级数即可。
#7
迭代法速度最快
#8
用快速截弦法比较好.只有-和*的运算.
以下是转自colacoca兄的话:
牛顿法突出优点是收敛的速度快。但它有个明显的缺点:需要计算导数f'(x),如果函数f(x)比较复杂,使用牛顿法是不方便的。
为了避开导数计算,就用差商:
(f(Xk)-f(X0))/(Xk-X0)
......
用以替换牛顿公式中得导数f'(Xk)
最后得
Xk+1=Xk-f(Xk)*(Xk-X0)/(f(Xk)-f(X0))
求得的Xk+1其实就是弦线与X轴的交点,所以上面的算法称弦截法
然后又是一阵推导.....
......
最后,为了加快收敛速度,改用差商
(f(Xk)-f(Xk-1))/(Xk-Xk-1)
得出快速弦截法的公式:
Xk+1=Xk-f(Xk)*(Xk-Xk-1)/(f(Xk)-f(Xk-1))
注:上面的Xk,Xk+1,Xk-1中的k,k-1,k+1都是X的下标,不是变量Xk减去1的意思
所以才有我的
x1=x0;
x0=x;
x=x0-(x0-x1)*(x0^2-A)/((x0^2-A)-(x1^2-A));
这3个式子
以下是转自colacoca兄的话:
牛顿法突出优点是收敛的速度快。但它有个明显的缺点:需要计算导数f'(x),如果函数f(x)比较复杂,使用牛顿法是不方便的。
为了避开导数计算,就用差商:
(f(Xk)-f(X0))/(Xk-X0)
......
用以替换牛顿公式中得导数f'(Xk)
最后得
Xk+1=Xk-f(Xk)*(Xk-X0)/(f(Xk)-f(X0))
求得的Xk+1其实就是弦线与X轴的交点,所以上面的算法称弦截法
然后又是一阵推导.....
......
最后,为了加快收敛速度,改用差商
(f(Xk)-f(Xk-1))/(Xk-Xk-1)
得出快速弦截法的公式:
Xk+1=Xk-f(Xk)*(Xk-Xk-1)/(f(Xk)-f(Xk-1))
注:上面的Xk,Xk+1,Xk-1中的k,k-1,k+1都是X的下标,不是变量Xk减去1的意思
所以才有我的
x1=x0;
x0=x;
x=x0-(x0-x1)*(x0^2-A)/((x0^2-A)-(x1^2-A));
这3个式子
#9
我用Borland C++ 3.1编写了一个算法,main调用sqrt计算2的算术平方根。更通用的算法只要更改一下main即可。这里的算法已经把原理解释的足够清楚。
本程序中,常数W表示数据的总位数,D标是小数部分位数。
#include <stdio.h>
#include <string.h>
const W=101;
const D=100;
int pos(int power){
return power+D;
}
int power(int pos){
return pos-D;
}
void fill(int d[W],int t){
for (int i=0;i<W;i++) d[i]=t;
}
void copy(int x[W],int y[W]){
for (int i=0;i<W;i++) y[i]=x[i];
}
void assign(int x[W],char* n, char* d){
fill(x,0);
char *p;
p=n;
int L=strlen(n);
int i;
for (i=L-1;i>=0;i--,p++) x[pos(i)]=*p-'0';
L=strlen(d);
p=d;
for (i=-1;i>=-L;i--,p++) x[pos(i)]=*p-'0';
}
int equal(int x[W],int y[W]){
for (int i=W-1;i>0;i--)
if (x[i]!=y[i]) return 0;
return 1;
}
void mid(int x[W],int y[W],int z[W]){
z[0]=x[0]+y[0];
for (int i=1;i<W;i++){
z[i]=x[i]+y[i]+z[i-1]/10;
z[i-1]=z[i-1]%10;
}
for (i=W-1;i>0;i--) {
z[i-1]+=(z[i]*10)%20;
z[i]/=2;
}
z[0]/=2;
}
void sqr(int x[W], int y[W]){
fill(y,0);
for (int i=0;i<W;i++){
for (int j=0;j<W;j++){
int t=pos(power(i)+power(j));
if ((t>=0)&&(t<W)) y[t]+=x[i]*x[j];
}
}
for (i=0;i<W-1;i++){
y[i+1]+=y[i]/10;
y[i]=y[i]%10;
}
y[W-1]=y[W-1]%10;
}
int compare(int x[W],int y[W]){
for (int i=W-1;i>=0;i--){
if (x[i]<y[i]) return -1;
if (x[i]>y[i]) return 1;
}
return 0;
}
void print(int x[W]){
int i;
for (i=W-1;i>=0;i--){
printf("%c",'0'+x[i]);
if (i==D) printf(".");
}
printf("\n");
}
void sqrt(int x[W],int y[W]){
int a[W],b[W],c[W];
fill(a,0);
copy(x,b);
b[pos(0)]++;
while (!equal(a,b)) {
mid(a,b,c);
sqr(c,y);
if (compare(y,x)<0) copy(c,a);
else copy(c,b);
}
copy(c,y);
return;
}
void main(){
int x[W],y[W];
assign(x,"2","0");
sqrt(x,y);
print(y);
}
本程序中,常数W表示数据的总位数,D标是小数部分位数。
#include <stdio.h>
#include <string.h>
const W=101;
const D=100;
int pos(int power){
return power+D;
}
int power(int pos){
return pos-D;
}
void fill(int d[W],int t){
for (int i=0;i<W;i++) d[i]=t;
}
void copy(int x[W],int y[W]){
for (int i=0;i<W;i++) y[i]=x[i];
}
void assign(int x[W],char* n, char* d){
fill(x,0);
char *p;
p=n;
int L=strlen(n);
int i;
for (i=L-1;i>=0;i--,p++) x[pos(i)]=*p-'0';
L=strlen(d);
p=d;
for (i=-1;i>=-L;i--,p++) x[pos(i)]=*p-'0';
}
int equal(int x[W],int y[W]){
for (int i=W-1;i>0;i--)
if (x[i]!=y[i]) return 0;
return 1;
}
void mid(int x[W],int y[W],int z[W]){
z[0]=x[0]+y[0];
for (int i=1;i<W;i++){
z[i]=x[i]+y[i]+z[i-1]/10;
z[i-1]=z[i-1]%10;
}
for (i=W-1;i>0;i--) {
z[i-1]+=(z[i]*10)%20;
z[i]/=2;
}
z[0]/=2;
}
void sqr(int x[W], int y[W]){
fill(y,0);
for (int i=0;i<W;i++){
for (int j=0;j<W;j++){
int t=pos(power(i)+power(j));
if ((t>=0)&&(t<W)) y[t]+=x[i]*x[j];
}
}
for (i=0;i<W-1;i++){
y[i+1]+=y[i]/10;
y[i]=y[i]%10;
}
y[W-1]=y[W-1]%10;
}
int compare(int x[W],int y[W]){
for (int i=W-1;i>=0;i--){
if (x[i]<y[i]) return -1;
if (x[i]>y[i]) return 1;
}
return 0;
}
void print(int x[W]){
int i;
for (i=W-1;i>=0;i--){
printf("%c",'0'+x[i]);
if (i==D) printf(".");
}
printf("\n");
}
void sqrt(int x[W],int y[W]){
int a[W],b[W],c[W];
fill(a,0);
copy(x,b);
b[pos(0)]++;
while (!equal(a,b)) {
mid(a,b,c);
sqr(c,y);
if (compare(y,x)<0) copy(c,a);
else copy(c,b);
}
copy(c,y);
return;
}
void main(){
int x[W],y[W];
assign(x,"2","0");
sqrt(x,y);
print(y);
}
#10
up