浮点数中的固定数字长度
我在网上看到很多关于这个话题的讨论,但还是找不到合适的解决办法。
我想把一些数字画出来,这些数字的长度各不相同,但我希望它们都有相同的位数。
比如说,我有:12.345678
和1.2345678
。现在,因为我需要把它们和误差一起画出来,所以我希望每个数字的格式都不一样,以便突出它们的有效数字。
所以,我想用不同的小数位数来画这些数字。在我的情况下,画23.45678+/-1.23456
没有意义,画成23.4+/-1.2
更好。另一方面,我需要把1.234567+/-0.034567
变成1.23+/-0.03
。
所以,假设我想把所有数字都画成固定宽度,可能是总共3位数字加上小数点。我应该使用类似'%1.1f' %num
的方式,但我找不到正确的方法。我该怎么做呢?
1 个回答
3
我建议你定义一个类,这个类可以用来解释字符串格式化,让你得到想要的结果。
在这个类里面,你需要确定浮点数的整数部分有多长,然后用这个长度来定义合适的字符串格式。
简单来说,如果你的输入是 12.345
(因为小数点前有两个数字),这个类会创建一个像 '{:4.1f}'
这样的格式;如果你的输入是 1.2345
(因为小数点前只有一个数字),那么它会生成 {:4.2f}
的格式。这里的总数字位数(这个例子中是 4
)是你输入的内容。
新的格式化器是 {:nQ}
,其中 n
是总的数字位数(所以在上面的例子中,你需要指定 {:4Q}
来得到你想要的输出)。
下面是代码:
import math
class IntegerBasedFloat(float):
def __format__(self, spec):
value = float(self)
# apply the following only, if the specifier ends in Q
# otherwise, you maintain the original float format
if spec.endswith('Q'):
# split the provided float into the decimal
# and integer portion (for this math is required):
DEC, INT = math.modf(value)
# determine the length of the integer portion:
LEN = len(str(abs(int(INT))))
# calculate the number of available decimals
# based on the overall length
# the -1 is required because the separator
# requires one digit
DECIMALS = int(spec[-2]) - LEN - 1
if DECIMALS < 0:
print 'Number too large for specified format'
else:
# create the corresponding float formatter
# that can be evaluated as usual:
spec = spec[-2] + '.' + str(DECIMALS) + 'f'
return format(value, spec)
DATA = [12.345, 2.3456, 345.6789]
print '{:4Q}'.format(IntegerBasedFloat(DATA[0]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[1]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[2]))
print 'This is a "custom" float: {:5Q} and a "regular" float: {:5.3f}'.format(IntegerBasedFloat(12.3456),12.3456)
输出应该是:
12.3
2.35
346
This is a "custom" float: 12.35 and a "regular" float: 12.346
这个回答的灵感来源于:
- 在Python中将数字分成整数和小数部分
- 为字符串格式化添加自定义转换类型