如果我有Python的Decimal,我如何可靠地获取数字的精确十进制字符串(即,不是科学计数法)表示形式而不尾随零?

例如,如果我有:

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

我想:
>>> get_decimal_string(d)
'0.00000000000001'

然而:
  • Decimal类没有任何to_decimal_string方法,甚至没有任何to_radix_string(radix)(cf:https://docs.python.org/3/library/decimal.html#decimal.Context.to_eng_string)
  • %f格式化程序默认默认舍入到小数点后6位-'%f' %(d, ) ==> '0.000000'-或要求精确的小数位数。
  • {:f}.format(...)格式化程序似乎可以正常工作-'{:f}'.format(d)==> '0.00000000000001'-但是我不愿意相信,因为它实际上与the documentation相反,后者表示“'f'…将数字显示为定点数字。默认精度为6”
  • 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)指出:



    因此,Decimal.__format__方法是python的字符串格式将用来生成str值的Decimal表示形式的方法。基本上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
    

    关于python - 获取Python十进制的精确十进制字符串表示形式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54013614/

    10-16 18:16