繁体   English   中英

获取 Python Decimal 的精确十进制字符串表示?

[英]Get precise decimal string representation of Python Decimal?

如果我有一个 Python Decimal ,我怎样才能可靠地获得数字的精确十进制字符串(即,不是科学记数法)表示而没有尾随零?

例如,如果我有:

>>> d = Decimal('1e-14')

我想:

>>> get_decimal_string(d)
'0.00000000000001'

然而:

  1. Decimal类没有任何to_decimal_string方法,甚至没有任何to_radix_string(radix) (参见: https : to_radix_string(radix)
  2. %f格式化程序默认四舍五入到 6 个小数位 - '%f' %(d, ) ==> '0.000000' - 或者需要精确的小数位数。
  3. {:f}.format(...)格式化程序似乎可以工作 - '{:f}'.format(d) ==> '0.00000000000001' -但是我不愿意相信这一点,因为这实际上与文档,上面写着“ 'f' ……将数字显示为定点数。默认精度为 6”
  4. Decimal.__repr__Decimal.__str__有时会返回科学记数法: repr(d) ==> "Decimal('1E-14')"

那么,有没有办法从 Python Decimal获取十进制字符串? 还是我需要使用Decimal.as_tuple()自己滚动?

简短的回答:

>>> d
Decimal('1E-14')
>>> '{:f}'.format(d)
'0.00000000000001'

长答案:

正如Brandon Rhodes指出的PEP 3101 (这是字符串格式 PEP)所述:

格式说明符的语法是开放式的,因为类可以覆盖标准格式说明符。 在这种情况下, str.format() 方法仅将第一个冒号和匹配大括号之间的所有字符传递给相关的基础格式化方法。

因此, Decimal.__format__方法是python 的字符串格式将用来生成Decimal值的str表示的方法。 基本上Decimal将格式覆盖为“智能”,但将默认为格式字符串设置的任何值(即{:.4f}会将小数截断为 4 位)。

这就是您可以信任它的原因(来自decimal.py:Decimal.__format__片段):

def __format__(self, specifier, context=None, _localeconv=None):
    #
    # ...implementation snipped.
    #

    # figure out placement of the decimal point
    leftdigits = self._exp + len(self._int)
    if spec['type'] in 'eE':
        if not self and precision is not None:
            dotplace = 1 - precision
        else:
            dotplace = 1
    elif spec['type'] in 'fF%':
        dotplace = leftdigits
    elif spec['type'] in 'gG':
        if self._exp <= 0 and leftdigits > -6:
            dotplace = leftdigits
        else:
            dotplace = 1

    # find digits before and after decimal point, and get exponent
    if dotplace < 0:
        intpart = '0'
        fracpart = '0'*(-dotplace) + self._int
    elif dotplace > len(self._int):
        intpart = self._int + '0'*(dotplace-len(self._int))
        fracpart = ''
    else:
        intpart = self._int[:dotplace] or '0'
        fracpart = self._int[dotplace:]
    exp = leftdigits-dotplace

    # done with the decimal-specific stuff;  hand over the rest
    # of the formatting to the _format_number function
    return _format_number(self._sign, intpart, fracpart, exp, spec)

长话短说, Decimal.__format__方法将根据Decimal._exp提供的取幂(在您的示例中为 14 位有效数字)计算必要的填充以表示小数点前后的数字。

>>> d._exp
-14

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM