| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1444 人关注过本帖
标题:【已解决】不调用math库求一个数开任意次根
只看楼主 加入收藏
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
结帖率:93.75%
收藏
已结贴  问题点数:20 回复次数:16 
【已解决】不调用math库求一个数开任意次根
我知道math.h里有个pow函数可以实现这个功能,不过我想知道我们不调用pow函数怎么实现这个功能。这是数学问题吧?有pow函数的代码吗


----------------------------------------

我在linux下用写了个f.c
如下:
#include<math.h>
main()
{
 pow(9.0,0.5);
 }
然后用gcc-E  gcc -S 得到的汇编指令是这个:
    .file    "f.c"
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    popl    %ebp
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.5.0"
    .section    .note.GNU-stack,"",@progbits
看不懂汇编
怎么弄啊
——————————————————
弄出了个半成品,由于用了幂级数展开求自然对数,底数a只能在很小(小于2)的时候才行,math库是怎么求对数的啊?
程序代码:
求a的b次,a,b为实数
#include<stdio.h>
#include<math.h>
double nci(double k,int r) //求r个k相乘
{
  int i;

  double b=1;

   if (r==0)return 1;
  for (i=1;i<=r;i++) b=b*k;
  return b;
}
double mln(double a)//手写的求自然对数
{
int i,coo;double x,ans;
x=a-1;ans=0;coo=1;
for (i=1;i<100;i++){
ans += coo*nci(x,i)/i;coo=coo*(-1);}
return ans;

}
double jiec(int i)//求阶乘
{

int j; double ans=1;if (i==0) return 1;
for (j=2;j<=i;j++)
ans *=j;
return ans;
}

double mexp(double ab)//手写求e的ab次
{
int i;double ans=0;
for (i=0;i<100;i++)
ans += nci(ab,i)/(jiec(i)*1.0);
return ans;
}

main()
{
double a,b;
printf("enter a,b : ");
scanf("%lf %lf",&a,&b);

printf("mln a is %lf\n",mln(a));//输出a的自然对数
printf("log a is %lf\n",log(a));//调用math库输出a的自然对数

printf("answer is %lf\n",mexp(b*mln(a)));//输出a的b次
printf("pow answer is %lf \n",pow(a,b));//调用math库输出a的b次
}

---------
改进后的代码见https://bbs.bccn.net/thread-331356-1-1.html

[ 本帖最后由 zjsxwc 于 2011-1-21 14:38 编辑 ]
搜索更多相关主题的帖子: linux 
2011-01-20 11:48
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
想来想去用2分法只写了个求一个数开任意正整数次根的代码,这个pow函数是怎么实现的啊
 n^(1/r) r为大于1的整数 n>0;
#include<stdio.h>
#include<math.h>
double nci(double k,int r) //求r个k相乘
{
  int i;
  double b=1;
  for (i=1;i<=r;i++) b=b*k;
  return b;
}
main()
{
 int r;
 double n,k,a,b;
 scanf("%lf",&n);// 求 n^(1/r) r为大于1的整数 n>0;
 scanf("%d",&r);
 k=n/2.0;a=0;b=n;
 while ((b-a)>1e-9)
 {
  if (nci(k,r)>n)
   {
    b=k;
    k=(a+b)/2.0;
   }
  else
   {
    a=k;
    k=(a+b)/2.0;
   }
 }
 printf("%6lf=%5lf^(1/%d)\n",k,n,r);
 printf("%6lf=%5lf^(1/%d)\n",pow(n,1.0/r),n,r);//调用pow函数结果
}

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-01-20 11:53
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
如果想写高效次方根,可以用分段,在什么范围内在那段,不可能一口吃出肥仔

小代码,大智慧
2011-01-20 12:01
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
楼上,有什么思路吗,我想求的是一个数的任意实数次,当然和本帖求某个数的开任意次根是一样的,比如 5.9的1.345次是10.884186,9.0的0.5次是3.0

[ 本帖最后由 zjsxwc 于 2011-1-20 12:13 编辑 ]

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-01-20 12:10
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
如果要稳定的,要用到字符串处理,字符串大数除法与字符串大数乘法,可是效率就。。。所以稳定与速度找一个平衡点

小代码,大智慧
2011-01-20 12:19
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
以下是引用点线面在2011-1-20 12:19:58的发言:

如果要稳定的,要用到字符串处理,字符串大数除法与字符串大数乘法,可是效率就。。。所以稳定与速度找一个平衡点

答非所问

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-01-20 12:35
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:0 
pow(a, b) => exp(ln(b) / ln(a))   (对数换底公式)
ln(n)的计算比较麻烦,要用通常的幂级数展开式的变形来计算,不然收敛极慢
而exp就直接套e^n的公式就可以了,那个公式计算速度非常快

樱之雪,晓之车
2011-01-20 12:40
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
exp(ln(b) / ln(a)) 不是等于 b/a吗 ,我要求的是pow(a, b),也就是 a的b次 ( a^b )应该是exp(b * ln(a))

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-01-20 12:48
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
ln (1+x) = x- x^2 /2 + ……而且这个展开还要求x是在-1到1之间的,否则x比较大偶的话展开后的结果不对
exp公式是
e^x = 1+x+x^2/2!+…… x范围没限制

[ 本帖最后由 zjsxwc 于 2011-1-20 13:25 编辑 ]

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-01-20 12:53
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:17 
以下是引用zjsxwc在2011-1-20 12:48:49的发言:

exp(ln(b) / ln(a)) 不是等于 b/a吗 ,我要求的是pow(a, b),也就是 a的b次 ( a^b )应该是exp(b * ln(a))
刚算错了,不过不影响我的表达,总之就是把ln和exp的幂级数展开,套进去计算就可以了

樱之雪,晓之车
2011-01-20 12:56
快速回复:【已解决】不调用math库求一个数开任意次根
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019030 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved