我对 Python 还很陌生,想知道如何在不使用任何小数模块或浮点的情况下控制任何给定数字的小数精度(例如:“%4f”%n)。
示例(编辑):
输入(2/7)
0.28571428571....
输入(1/3)
0.33333333333333....
我希望它们达到千位小数点或任何小数点。我正在考虑使用一段时间作为受控循环,但我不确定该怎么做。谢谢
编辑:我不使用十进制模块的原因是我可以概念化这些类型事物背后的算法/逻辑。只是试图真正理解事物背后的逻辑。
我对 Python 还很陌生,想知道如何在不使用任何小数模块或浮点的情况下控制任何给定数字的小数精度(例如:“%4f”%n)。
示例(编辑):
输入(2/7)
0.28571428571....
输入(1/3)
0.33333333333333....
我希望它们达到千位小数点或任何小数点。我正在考虑使用一段时间作为受控循环,但我不确定该怎么做。谢谢
编辑:我不使用十进制模块的原因是我可以概念化这些类型事物背后的算法/逻辑。只是试图真正理解事物背后的逻辑。
我们可以使用 along
来存储一个高精度的小数,并对其进行算术运算。以下是您将其打印出来的方式:
def print_decimal(val, prec):
intp, fracp = divmod(val, 10**prec)
print str(intp) + '.' + str(fracp).zfill(prec)
用法:
>>> prec = 1000
>>> a = 2 * 10**prec
>>> b = a//7
>>> print_decimal(b, prec)
0.2857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857
如果没有 Decimal 模块(为什么?),假设 Python 3:
def divide(num, den, prec):
a = (num*10**prec) // den
s = str(a).zfill(prec+1)
return s[0:-prec] + "." + s[-prec:]
感谢@nneonneo 的聪明.zfill()
想法!
>>> divide(2,7,1000)
'0.28571428571428571428571428571428571428571428571428571428571428571428571428571
42857142857142857142857142857142857142857142857142857142857142857142857142857142
85714285714285714285714285714285714285714285714285714285714285714285714285714285
71428571428571428571428571428571428571428571428571428571428571428571428571428571
42857142857142857142857142857142857142857142857142857142857142857142857142857142
85714285714285714285714285714285714285714285714285714285714285714285714285714285
71428571428571428571428571428571428571428571428571428571428571428571428571428571
42857142857142857142857142857142857142857142857142857142857142857142857142857142
85714285714285714285714285714285714285714285714285714285714285714285714285714285
71428571428571428571428571428571428571428571428571428571428571428571428571428571
42857142857142857142857142857142857142857142857142857142857142857142857142857142
85714285714285714285714285714285714285714285714285714285714285714285714285714285
7142857142857142857142857142857142857142857'
警告:这使用地板除法,所以divide(2,3,2)
会给你0.66
而不是0.67
.
虽然其他答案使用非常大的值来处理精度,但这实现了长除法。
def divide(num, denom, prec=30, return_remainder=False):
"long divison"
remain=lim=0
digits=[]
#whole part
for i in str(num):
d=0;remain*=10
remain+=int(i)
while denom*d<=remain:d+=1
if denom*d>remain:d-=1
remain-=denom*d
digits.append(d)
#fractional part
if remain:digits.append('.')
while remain and lim<prec:
d=0;remain*=10
while denom*d<=remain:d+=1
if denom*d>remain:d-=1
remain-=denom*d
digits.append(d)
lim+=1
#trim leading zeros
while digits[0]==0 and digits[1]!='.':
digits=digits[1:]
quotient = ''.join(list(map(str,digits)))
if return_remainder:
return (quotient, remain)
else:
return quotient
因为它是除法算法,所以每个数字都是正确的,你可以得到余数(不像没有余数的地板除法)。我在这里实现的精度是小数点后的位数。
>>> divide(2,7,70)
'0.2857142857142857142857142857142857142857142857142857142857142857142857'
>>> divide(2,7,70,True)
('0.2857142857142857142857142857142857142857142857142857142857142857142857', 1)