编写指数函数

使用数值算法进行指数函数的编写,满足【所有正实数为底数,任意实数为指数的指数函数计算】

本程序,使用规范化的编程【注释,分段,变量定义,常量定义】
使用牛顿迭代法计算N次方根,并且初始值采用自动计算。

程序运行结果:
Please Input the Power Number:989
Please Input the Power Index:12.333
You have input fbaseNum, PowerIndex 989 12.333
power(989.00000000000000 , 12.33300000000000)=8.7047412120061421392e+36

计算器运行的结果:
8.7047412120061422565207046539945e+36‬

有效数字达到16位

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Author:@MikeLiu
# Date 2020-02-20

import decimal

def FMatF_TEN(x):
	return decimal.Decimal("%.14f" % float(x))

'''
'定义常量,确定计算的精度'
'''
ELPSILON = FMatF_TEN(1.0e+13)      ## 设置小数转分数的 精度范围
INFINUM =  FMatF_TEN(1.7e+307)     ## 设置最大计算值
ELPS =     FMatF_TEN(1.0e-13)      ## 求N次方根的 精度控制
ELPS_E =   FMatF_TEN(0.005)        ## 求N次方根时 初值的控制范围
ZERO   = 0
ONE    = 1

###############################################################
def Is_Prime(iNum_a, iNum_b):          ## 判断两个数字是否互质
	while iNum_b != ZERO:
		iNum_a, iNum_b = (iNum_b, iNum_a%iNum_b)
	return iNum_a

###############################################################
class CPowerE:                          ## Caclulate the Power(fBase,iIndex)

	def powerE(self,fbase,iexponent):   ## 计算整数指数函数值
		flag=ONE
		Ret=FMatF_TEN(1.0)
		tmp=fbase
		if iexponent==ZERO:				## 指数为 0 结果为 1
			return ONE
			
		if iexponent<ZERO:		            ## 指数为 负数 按照正数计算,结果取倒数【参看最后返回结果】
			flag=ZERO		                ## 定义标志位 flag 【0:负数; 1:正数】
			iexponent=abs(iexponent)
					
		while iexponent>ZERO:		        
			if iexponent&1==ONE:          ## 指数 跟 1 做与运算,判断是奇数,则乘以底数
				Ret=Ret*tmp
			iexponent>>=ONE 		        ## 指数 跟 1 做与运算,判断是偶数,底数的平方,并且指数右移【相当于除以2取整】
			tmp=tmp*tmp
			if(tmp>INFINUM):            ## 如果乘出来的超过最大数 INFINUM 就取最大值
				tmp=INFINUM
		return Ret if flag else 1/Ret   ## 最后返回计算结果,并且判断标志位,根据正负情况取值
		
	def powerW(self,fbase,n):           ## 求 M 的 N次方根 函数 【牛顿迭代算法,自动设置初值】
		X = fbase /n                    ## 初始值默认取法
		iTemp = 0
		if(X < ELPS_E):                 ## 初始值过小,则取自己本身 (数值除以 n 所以不会出现大数值)
			X = fbase/2

		while (X!=ZERO):
			iTemp = X			
			'''
			' 牛顿迭代算法,请参看网址:https://www.cnblogs.com/houkai/p/3332520.html'
			'''
			U_1 = FMatF_TEN(self.powerE(X,n))-FMatF_TEN(fbase)
			if(U_1>INFINUM):
				U_1=INFINUM
			U_2 = FMatF_TEN(n*self.powerE(X,n-1))
			if(U_2==0):
				U_2=X                    ## 如果精度控制,导致计算出的过程值变成0 则取 X 代替
			elif(U_2>INFINUM):
				U_2=INFINUM              ## 如果精度控制,导致计算出的过程值变成无穷大 则取 INFINUM 代替

			X = X - U_1/(U_2)
			if((abs(X - iTemp) < ELPS)):
				return X
	
###############################################################			
class CDecToFract:                         ## 小数转换成分带数 格式 【整数,分子,分母】 3.25=3+1/4=[3, 1, 4]

	def DecToFract(self,fPoint):	
		Data=[]
		Data.append(int(fPoint))		    ## 取整放在数组 Data[] 第一个位置 Data[0]
		fDeci = FMatF_TEN(fPoint - Data[0]) ## 取小数部分
		iNum_a = int(fDeci*ELPSILON)        ## 小数部分放大 ELPSILON 倍数作为分子初始值
		iNum_b = int(ELPSILON)		        ## ELPSILON 本身作为分母初始值
		
		itmp = Is_Prime(iNum_a, iNum_b)     ## 判断分子分母是否互质
		
		while (1 != itmp):                  ## 如果不互质,采用辗转相除法,进行约分化简
			iNum_a /= itmp
			iNum_b /= itmp
			itmp = Is_Prime(iNum_a, iNum_b)
		
		Data.append(int(iNum_a))		   ##  分子放在数组 Data[] 第二个位置 Data[1]
		Data.append(int(iNum_b))		   ##  分母放在数组 Data[] 第三个位置 Data[2]	
		
		return Data

###############################################################
'''
' 指数函数的基本计算法则: '
' power(3,2.75) = power(3,2+3/4) = power(3,2) * power(3,3/4) = power(3,2)*power(power(3,1/4),3) = 20.51556351259'
'''
def power(fbase,iexponent):                ## Calulate 指数函数的计算方式
	Dect=CDecToFract()
	
	fNum=FMatF_TEN(fbase)        ## 输入数值,取十位有效数字
	iIndex=FMatF_TEN(iexponent)  ## 输入数值,取十位有效数字
	
	ARet=Dect.DecToFract(iIndex)           ## 通过小数化分数的类处理指数参数
	PowerE = CPowerE()

	if(ARet[1]==0):                        ## 如果分子是0 直接使用指数计算类,调用整数的指数函数计算法
		return PowerE.powerE(fNum,int(iIndex))
	else:		                           ## 如果分子不是0 整数部分调用整数的指数函数计算法,分母用底数的方根计算,分支用方根计算后的整数计算,最后做乘法
		A=PowerE.powerE(fNum,int(ARet[0]))
		B=PowerE.powerW(fNum,int(ARet[2]))
		C=PowerE.powerE(B,int(ARet[1]))
		Ret=A*C
		return  Ret

if __name__ == '__main__': 
	fNum=input("\n\nPlease Input the Power Number:")
	iIndex=input("Please Input the Power Index:")

	print("\nYou have input fbaseNum, PowerIndex",fNum,iIndex)

	fNum = FMatF_TEN(fNum)
	iIndex = FMatF_TEN(iIndex)

	Ret = '%.20g'%(power(fNum,iIndex))    ## 科学计数法 保留20位有效数字
                     
	print ("power(",fNum," , ", iIndex,")","=",Ret,sep='')  
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值