【问题标题】:Adaptive floating point formatting自适应浮点格式
【发布时间】:2020-01-08 21:00:36
【问题描述】:

这似乎是一个非常愚蠢的问题,但老实说,我无法找到令人满意的解决方案。到目前为止,我发现的所有“显而易见”的解决方案都有一些隐藏的问题。

我想将浮点值格式化为任意宽度相对精度,同时保持{:g}格式说明符的自适应格式。 (使用科学记数法或正规记数法,取决于数字的大小)

给定:

import math               # Here is how the default (str) formatting displays these values

# Small values
long_small = 10**-16/3    # 3.3333333333333335e-17
short_small = 10**-16     # 1e-16

# Medium values
long_medium = math.pi     # 3.141592653589793
short_medium = 130.0      # 130.0

# Large values
long_large = 10.0**16 + 2 # 1.0000000000000002e+16
short_large = 10.0**16    # 1e+16

在任意 width 的情况下,我想将这些数字格式化如下(例如,width=8):

long_small    # 3.33e-17
short_small   # 1.00e-16
long_medium   # 3.141593
short_medium  # 130.0000
long_large    # 1.00e+16
short_large   # 1.00e+16

在任意相对精度的情况下,我想将这些数字格式化如下 (precision=8):

long_small    # 3.33333333e-17
short_small   # 1.00000000e-16
long_medium   # 3.14159265
short_medium  # 130.000000
long_large    # 1.00000000e+16
short_large   # 1.00000000e+16
  • {:N.Mf} 不够好,因为我想为非常大和非常小的数字保留科学记数法格式
  • {:N.Mg}{:N.M} 还不够好,因为它们会丢弃尾随零,以及用空格填充的“宽度”说明符,而不是添加数字
  • {:N.Me} 始终使用科学计数法
  • 任何使用>0<0 的“聪明的技巧”都不起作用,因为它要么添加前导零,要么在尾数后添加零
  • 任何“聪明的黑客”,尝试使用{:f}{:e} 格式化并尝试使用.replace(...)[:fixed_width] 生成的字符串都不起作用,因为各种边缘情况,它会改变数字,截去尾数或浮点数(.

【问题讨论】:

    标签: python floating-point formatting


    【解决方案1】:

    叹息。我想我在写问题时找到了解决方案,但我对它的工作方式不太满意。

    任意相对精度部分被证明是相当容易的。经过一番挖掘,我在文档中找到了# 格式修饰符。它使用“替代形式”形式进行转换(无论这意味着什么)。

    所以使用{:#.9g},您可以获得我所说的precision=8。不幸的是,当浮点点 (.) 位于末尾时,它的行为有点奇怪。例如,f"{10.0**8:#.9g}" 产生 100000000.,而我希望它直接转到 1.00000000e+08。但是哦,好吧。

    任意 width 部分有点难。最后,我能想到的最好的是:

    def fmt_fixed_width(value, width):
        assert width >= 7
        result = "{:#.{}g}".format(value, width - 1) 
        if len(result) != width: 
            result = "{:#.{}g}".format(value, width - 1 + width - len(result)) 
        return result
    

    显然,这不是我想要的漂亮、优雅的解决方案。如果有人知道,如何获得正确的任意 width 浮点格式,请告诉我。

    【讨论】:

      【解决方案2】:

      您正在使用格式类型“g”,它最接近您的要求,但它有一些与您的逻辑不匹配的任意硬编码逻辑。见这里:https://docs.python.org/3.7/library/string.html#format-specification-mini-language

      特别是当它选择格式化为“f”或“e”时。

      关于固定宽度的情况,您的标准非常特殊。对于数字,通常会考虑精度,而不是用于编码的实际字符数。你所谓的“相对精度”。 AFAIK,没有内置功能。

      不过,我认为它比您的方法更容易完成。只需对 >=1 和

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多