我如何格式化一个浮点数,使它不包含尾随零?换句话说,我希望得到的字符串尽可能短。

例如:

3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"

当前回答

我呢,我会用('%f' % x).rstrip('0').rstrip('.')——保证定点格式,而不是科学符号,等等。是的,不像%g那么流畅和优雅,但是,它是有效的(而且我不知道如何强迫%g永远不使用科学符号;-)。

其他回答

在看了几个类似问题的答案后,这似乎是我最好的解决方案:

def floatToString(inputValue):
    return ('%.15f' % inputValue).rstrip('0').rstrip('.')

我的推理:

%g并没有摆脱科学符号。

>>> '%g' % 0.000035
'3.5e-05'

小数点后15位似乎可以避免奇怪的行为,并且对我的需求有足够的精度。

>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'

我可以使用format(inputValue, '.15f')。而不是'%。inputValue,但这有点慢(~30%)。

我本可以使用Decimal(inputValue).normalize(),但这也有一些问题。首先,它慢了很多(~11倍)。我还发现,尽管它具有相当高的精度,但在使用normalize()时,它仍然会遭受精度损失。

>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')

最重要的是,我仍然会从浮点数转换为十进制,这可能会让你得到其他东西,而不是你在那里输入的数字。我认为十进制工作最好时,算术保持在十进制和十进制初始化的字符串。

>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')

我确信Decimal.normalize()的精度问题可以使用上下文设置调整为所需的精度,但考虑到已经较慢的速度和不需要荒谬的精度,以及我仍然从浮点数转换并失去精度的事实,我认为不值得继续下去。

我不关心可能的“-0”结果,因为-0.0是一个有效的浮点数,它可能是一个罕见的发生,但既然你提到你想保持字符串结果尽可能短,你总是可以使用一个额外的条件在非常小的额外速度成本。

def floatToString(inputValue):
    result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
    return '0' if result == '-0' else result

尝试一下,它将允许你添加一个“精度”变量来设置你想要的小数点后多少位。只要记住它会四舍五入。请注意,这只适用于字符串中有小数的情况。

 number = 4.364004650000000
 precision = 2
 result = "{:.{}f}".format(float(format(number).rstrip('0').rstrip('.')), precision)

输出

 4.364004650000000
 4.36

如果你想要一些既适用于数字输入又适用于字符串输入的东西(感谢@mike-placentra的bug搜索):

def num(s):
    """ 3.0 -> 3, 3.001000 -> 3.001 otherwise return s """
    s = str(s)
    try:
        int(float(s))
        if '.' not in s:
            s += '.0'
        return s.rstrip('0').rstrip('.')
    except ValueError:
        return s

>>> for n in [3, 3., 3.0, 3.1, 3.14, 3.140, 3.001000, 30 ]: print(num(n))
... 
3
3
3
3.1
3.14
3.14
3.001
30

>>> for n in [3, 3., 3.0, 3.1, 3.14, 3.140, 3.001000, 30 ]: print(num(str(n)))
... 
3
3
3
3.1
3.14
3.14
3.001
30
>>> str(a if a % 1 else int(a))

“(5g)。”format (x)

我用这个来格式化浮点到尾零。