具有可变精度的百分比
我想显示一个百分比,保留三位小数,除非这个百分比大于99%。如果大于99%,我希望显示这个数字,保留所有的9和后面加上三个不是9的字符。
我该怎么用Python来实现这个呢?"%.8f"
这种字符串格式化方法还不错,但我需要确保在最后一串9之后保留最后三个字符。
举个例子:
54.8213% 变成 54.821%
95.42332% 变成 95.423%
99.9932983% 变成 99.99330%
99.99999999992318 变成 99.9999999999232%
6 个回答
1
def ceilpowerof10(x):
return math.pow(10, math.ceil(math.log10(x)))
def nines(x):
return -int(math.log10(ceilpowerof10(x) - x))
def threeplaces(x):
return ('%.' + str(nines(x) + 3) + 'f') % x
请注意,nines() 在处理那些本身就是10的幂的数字时会出错。如果想让它对所有输入都安全使用,还需要做一些额外的工作。另外,处理负数时可能也会有一些问题。
2
Mark Ransom的回答真是太棒了。只要稍微动动手,就能解决任何输入的问题。我已经把这点小工作做了。
你只需要在nines()里面加一些代码:
def nines(x):
x = abs(x) # avoid exception caused if x is negative
x -= int(x) # keep fractional part of x only
cx = ceilpowerof10(x) - x
if 0 == cx:
return 0 # if x is a power of 10, it doesn't have a string of 9's!
return -int(math.log10(cx))
这样,threeplaces()就可以处理任何情况了。下面是几个测试案例:
>>> threeplaces(0.9999357)
'0.9999357'
>>> threeplaces(1000.9999357)
'1000.9999357'
>>> threeplaces(-1000.9999357)
'-1000.9999357'
>>> threeplaces(0.9900357)
'0.99004'
>>> threeplaces(1000.9900357)
'1000.99004'
>>> threeplaces(-1000.9900357)
'-1000.99004'
3
试试这个:
import math
def format_percentage(x, precision=3):
return ("%%.%df%%%%" % (precision - min(0,math.log10(100-x)))) % x