【问题标题】:Fixed digits number in floats浮点数中的固定位数
【发布时间】:2014-10-01 13:28:17
【问题描述】:

我在 SE 上阅读了很多关于此的讨论,但仍然找不到合适的。

我想用相同的位数绘制一些不同长度的数字。

例如我有:12.3456781.2345678。现在,由于我必须用它们的错误来绘制它们,我希望每个都有不同的格式,以便它们有意义。

所以,我想用可变的小数位数绘制它们。就我而言,绘制23.45678+/-1.23456 是没有意义的,但更好的是23.4+/-1.2。另一方面,我需要1.234567+/-0.034567 变成1.23+/-0.03

所以,假设我想绘制所有具有固定宽度的数字,总共可以是 3 位数字加上逗号。我应该使用'%1.1f' %num 之类的东西,但我找不到正确的方法。我该怎么做?

【问题讨论】:

  • @Schorsch,不完全是。问题是,在我的情况下,小数位数是可变的,根据整数部分和值的错误。我只需要修复总位数而不是小数位数。
  • @Schorsch,在您的示例中,我应该提前知道小数位数,但事实并非如此,而且我必须在代码中添加更多变量(DECIMALS 列表)。相反,我更喜欢“自洽”的解决方案,一种根据自身特点自行安排的格式。

标签: python number-formatting digits fixed-width


【解决方案1】:

我建议定义一个类来解释字符串格式化程序以提供您想要的内容。
在该类中,您可以确定浮点数的整数部分的长度,并使用它来定义适当的字符串格式。
简而言之,如果您的输入是 12.345(因为您在小数点分隔符前有两位数),该类将创建一个像 '{:4.1f}' 这样的格式化程序,如果您的输入是 1.2345(因为您之前只有一位小数点分隔符)。总位数(本例中为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

这个答案的灵感来自:
- splitting a number into the integer and decimal parts in python
- Add custom conversion types for string formatting

【讨论】:

  • @downvoter 您是否愿意解释为什么这个答案没有帮助,它如何不能回答问题或者它可能有什么问题?如果这个提议有不必要的负面影响,我特别感兴趣。
猜你喜欢
  • 1970-01-01
  • 2015-03-28
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多