输入实数X,泰勒公式计算 2的负X次方 的值?

时间:2022-08-23 08:36:48
输入实数X,
   
根据指定精度用泰勒公式计算 2的负X次方 的值?

谁有公式 和代码?

18 个解决方案

#1


试一下这个:

2^(-x) = (1/2)^x
       = e^(log(1/2)*x)

于是可以定义
double power_e_x(double x)
{
    return 1 + x + x*x/2 + x*x*x/6 + ... //根据精度自己改成判断性的语句吧
}

double power_2_neg_x(double x)
{
    return power_e_x(log(1/2) * x);
}

调用power_2_neg_x(x)就行了。

#2


to gambolgs(Gambol) :
谢谢你的答复,还有点问题,

long(x)又用什么公式?可以不用函数库里面的log吗?

#3


log就是ln啊,e为底数的对数。
C函数库里的log(x)就是国内数学教材上常用的ln(x)。相信精度已经足够了。如果你要求够高可以用别的数学软件算一个精确值,换成常数放进去(我的正好被反安装了没法算)。

#4


gambolgs(Gambol),还得马烦你一下,
下面程序好像还是有问题,会出错,计算不了。
lnxXP1和myexp两个函数已经验证是正确的。



#include <iostream.h>
#include <math.h>


/* ln(1+x)=x - x^2/2 + x^3/3 +... + (-1)^(n-1)*x^n/n  (n=1,2,3,...) */
double lnXP1(double x, double d)
{
  int n=1,k=1;
  double z,j=x,y=0;
  do
  {
    z=k*j/n;
    y+=z;
    k*=-1;
    j*=x;
    n++;  
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d); */

  return y; 
}


/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  int i=0,m=1;
  double z,y=0,j=1;
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return y;
}
  

/* 2^(-x) = (1/2)^x = e^(ln(1/2)*x)  */
double pow2(double x, double d)
{  
  /*return myexp(log(1/2)*x,d);*/  
  return myexp(lnXP1(1/2,d)*x,d); */
 }


void main()
{
  double x;
  cin>>x;
  cout<<"pow2(x)="<<pow2(x,0.0001)<<endl;
}

#5


double pow2(double x, double d)
{  
  return myexp(lnXP1(0.5,d)*x,d);
 }

You may not use 1/2, use 0.5 instead as 1/2 == 0.

#6


指定精度。。。那个。。。微积分课程学过误差估计的。。。忘了。。。查查。。。

#7


up

#8


double pow2(double x, double d)
{  
  return myexp(lnXP1(1,d)*x,d); 
 }

1/2要改成1计算的结果才是正确的,改成0.5还是计算不准确,为什么会这样?

#9


当x大一点的时候,比如是10的时候程序就动了?

#10


double pow2(double x, double d)
{  
  return myexp(lnXP1(-0.5,d)*x,d); 
 }

应该是-0.5,因为lnXP1(x) = ln(1 + x)
所以要求ln(.5) 应该是lnXP1(-0.5)

即使这样,这个程序也只对小范围的x正确(比如3,-3)
x太大了,级数收敛速度非常慢,还没算出结果那个阶乘和幂函数就越界了(比如x=10)

#11


double pow2(double x, double d)
{  
  return myexp(lnXP1(-0.5,d)*x,d); 
 }

我试过-0.5了,结果也不对,只有是1才能计算正确,奇怪了。

#12


我都记不得还改了那些地方了,反正下面这个程序我的电脑上是正常的。
输入3得到0.125019

#include <iostream>
#include <math.h>

using namespace std;

/* ln(1+x)=x - x^2/2 + x^3/3 +... + (-1)^(n-1)*x^n/n  (n=1,2,3,...) */
double lnXP1(double x, double d)
{
  int n=1,k=1;
  double z,j=x,y=0;
  do
  {
    z=k*j/n;
    y+=z;
    k*=-1;
    j*=x;
    n++;  
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d); */

  return y; 
}


/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  unsigned long int i=0,m=1;
  long double z,y=0,j=1;
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return (double)y;
}
  

/* 2^(-x) = (1/2)^x = e^(ln(1/2)*x)  */
double pow2(double x, double d)
{  
  /*return myexp(log(1/2)*x,d);*/  
double lg2 = -lnXP1(-.5, 1e-4);
  return myexp(- lg2 * x,d);
}

void main()
{
  double x;
  cin>>x;

  cout<<"pow2(x)="<<pow2(x,0.0001)<<endl;

  cin >> x;
}

#13


谢谢gambolgs(Gambol) !结分!

#14


谢谢各位!

#15


you are welcome

#16


最后是什么问题呢?

#17


gambolgs(Gambol)  你最后面的给的代码是正确的。

#18


应该溢出问题

/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  unsigned long int i=0,m=1;
  long double z,y=0,j=1;  //你改成long double就可以了。
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return (double)y;
}


/* 2^(-x) = (1/2)^x = e^(ln(0.5)*x)  */
double pow2(double x, double d)
{  
  double lg2 = -lnXP1(-.5, 1e-4);
  return myexp(- lg2 * x,d);
}

#1


试一下这个:

2^(-x) = (1/2)^x
       = e^(log(1/2)*x)

于是可以定义
double power_e_x(double x)
{
    return 1 + x + x*x/2 + x*x*x/6 + ... //根据精度自己改成判断性的语句吧
}

double power_2_neg_x(double x)
{
    return power_e_x(log(1/2) * x);
}

调用power_2_neg_x(x)就行了。

#2


to gambolgs(Gambol) :
谢谢你的答复,还有点问题,

long(x)又用什么公式?可以不用函数库里面的log吗?

#3


log就是ln啊,e为底数的对数。
C函数库里的log(x)就是国内数学教材上常用的ln(x)。相信精度已经足够了。如果你要求够高可以用别的数学软件算一个精确值,换成常数放进去(我的正好被反安装了没法算)。

#4


gambolgs(Gambol),还得马烦你一下,
下面程序好像还是有问题,会出错,计算不了。
lnxXP1和myexp两个函数已经验证是正确的。



#include <iostream.h>
#include <math.h>


/* ln(1+x)=x - x^2/2 + x^3/3 +... + (-1)^(n-1)*x^n/n  (n=1,2,3,...) */
double lnXP1(double x, double d)
{
  int n=1,k=1;
  double z,j=x,y=0;
  do
  {
    z=k*j/n;
    y+=z;
    k*=-1;
    j*=x;
    n++;  
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d); */

  return y; 
}


/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  int i=0,m=1;
  double z,y=0,j=1;
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return y;
}
  

/* 2^(-x) = (1/2)^x = e^(ln(1/2)*x)  */
double pow2(double x, double d)
{  
  /*return myexp(log(1/2)*x,d);*/  
  return myexp(lnXP1(1/2,d)*x,d); */
 }


void main()
{
  double x;
  cin>>x;
  cout<<"pow2(x)="<<pow2(x,0.0001)<<endl;
}

#5


double pow2(double x, double d)
{  
  return myexp(lnXP1(0.5,d)*x,d);
 }

You may not use 1/2, use 0.5 instead as 1/2 == 0.

#6


指定精度。。。那个。。。微积分课程学过误差估计的。。。忘了。。。查查。。。

#7


up

#8


double pow2(double x, double d)
{  
  return myexp(lnXP1(1,d)*x,d); 
 }

1/2要改成1计算的结果才是正确的,改成0.5还是计算不准确,为什么会这样?

#9


当x大一点的时候,比如是10的时候程序就动了?

#10


double pow2(double x, double d)
{  
  return myexp(lnXP1(-0.5,d)*x,d); 
 }

应该是-0.5,因为lnXP1(x) = ln(1 + x)
所以要求ln(.5) 应该是lnXP1(-0.5)

即使这样,这个程序也只对小范围的x正确(比如3,-3)
x太大了,级数收敛速度非常慢,还没算出结果那个阶乘和幂函数就越界了(比如x=10)

#11


double pow2(double x, double d)
{  
  return myexp(lnXP1(-0.5,d)*x,d); 
 }

我试过-0.5了,结果也不对,只有是1才能计算正确,奇怪了。

#12


我都记不得还改了那些地方了,反正下面这个程序我的电脑上是正常的。
输入3得到0.125019

#include <iostream>
#include <math.h>

using namespace std;

/* ln(1+x)=x - x^2/2 + x^3/3 +... + (-1)^(n-1)*x^n/n  (n=1,2,3,...) */
double lnXP1(double x, double d)
{
  int n=1,k=1;
  double z,j=x,y=0;
  do
  {
    z=k*j/n;
    y+=z;
    k*=-1;
    j*=x;
    n++;  
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d); */

  return y; 
}


/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  unsigned long int i=0,m=1;
  long double z,y=0,j=1;
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return (double)y;
}
  

/* 2^(-x) = (1/2)^x = e^(ln(1/2)*x)  */
double pow2(double x, double d)
{  
  /*return myexp(log(1/2)*x,d);*/  
double lg2 = -lnXP1(-.5, 1e-4);
  return myexp(- lg2 * x,d);
}

void main()
{
  double x;
  cin>>x;

  cout<<"pow2(x)="<<pow2(x,0.0001)<<endl;

  cin >> x;
}

#13


谢谢gambolgs(Gambol) !结分!

#14


谢谢各位!

#15


you are welcome

#16


最后是什么问题呢?

#17


gambolgs(Gambol)  你最后面的给的代码是正确的。

#18


应该溢出问题

/* e^x=1 + x/1! + x^2/2! + x^3/3! + ... + x^n/n!  (n=0,1,2,3,...)  */
double myexp(double x, double d)
{
  unsigned long int i=0,m=1;
  long double z,y=0,j=1;  //你改成long double就可以了。
  do
  {
    z=j/m;
    y+=z;
    j*=x;
    i++;
    m*=i;
  }while((z<-d)||(z>d));  /* }while(fabs(z)>d);  */
  return (double)y;
}


/* 2^(-x) = (1/2)^x = e^(ln(0.5)*x)  */
double pow2(double x, double d)
{  
  double lg2 = -lnXP1(-.5, 1e-4);
  return myexp(- lg2 * x,d);
}