在Python中对数字进行四舍五入但保留末尾零。

67

我一直在编写一个脚本,它从Excel电子表格中获取数据,将数字四舍五入并去掉小数点,例如,2606.89579999999变成了26069。但是,即使有一个尾随的零,我需要这个数字精确地保留两位小数,因此2606.89579999999应该变成260690。

目前,i从Excel单元格中获取数据,并将其舍入到两位小数(i = round(i, 2)),这给出了上面示例中的单个小数点。

我试图弄清楚如何使用Decimal让它起作用,但似乎无法让它正常工作。

所有其他被四舍五入的数字,如果舍入值不以“0”结尾,则使用round(i, 2)可以正常工作,但是如果数字刚好以*.x0结尾,那么这个0就会被删除并且会影响数据。


1
我想我刚刚弄明白了 - 使用 i = ('%.2f' %i) 似乎可以解决问题。我将使用其他数字进行测试以验证其是否有效。 - Seth Koberg
1
2606.89579999999 应该变成 260690 还是 2606.90? - shantanoo
@SethKoberg,如果你错过了我的十进制示例的话,我更新了我的答案(编辑了许多内容以使其更清晰和准确)。 - alko
这个回答解决了你的问题吗?在Python中将浮点数小数点后面添加零 - iacob
6个回答

86

由于您正在谈论尾随零,这是一个关于将数字表示为字符串的问题,您可以使用

>>> "%.2f" % round(2606.89579999999, 2)
'2606.90'

或者使用 format 函数来使用现代风格:

>>> '{:.2f}'.format(round(2606.89579999999, 2))
'2606.90'

使用 replacetranslate 命令来删除点号(_ 指的是 Python 控制台中上一个命令的结果):

>>> _.translate(None, '.')
'260690'

请注意,这里不需要舍入,因为.2f格式会应用相同的舍入:

>>> "%.2f" % 2606.89579999999
'2606.90'

但是既然你提到了Excel,你可能会选择自己编写舍入函数,或使用decimal,因为float.round由于浮点数表示而导致结果奇怪:

>>> round(2.675, 2)
2.67
>>> round(2606.89579999999, 2)
2606.89

使用 quantize 函数来处理十进制数:

>>> from decimal import *
>>> x = Decimal('2606.8950000000001')
# Decimal('2606.8950000000001')
>>> '{}'.format(x.quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN))
'2606.90'

那么,针对您的原始任务,变成了:

>>> x = Decimal('2606.8950000000001')
>>> int((x*100).quantize(1, rounding=ROUND_HALF_EVEN))
260690

而奇怪的四舍五入原因也随之呈现在Decimal面前:

>>> x = Decimal(2606.8950000000001)
# Decimal('2606.89499999999998181010596454143524169921875') # internal float repr

不需要进行 round 调用:.2f 已经为您完成了四舍五入。 - Mark Dickinson
2
%.2f 已经为您进行了四舍五入,因此您也可以使用:"%.2f" % (2606.89579999999)format(2606.89579999999, '.2f') - Ashwini Chaudhary
@MarkDickinson 不确定它是否完全以相同的方式舍入,实际上它确实是这样的。 - alko
@alko:大多数情况下是这样的。 :-) 不过在 Python 2.6 及更早版本中有一些奇怪的地方。但如果你坚持使用 Python 3 或 Python 2.7,就不会有问题。 - Mark Dickinson
@MarkDickinson 我刚刚检查了2.7和3.3的cP和PyPy,忘记了2.6 :) - alko
py3.7.12 round(2606.89579999999, 2)==2606.9 py3.7.12 round(2606.89579999999, 2)==2606.9 - Kermit

23

从Python 3.6开始,您还可以使用f-string来内联格式化数字。在这种情况下,所需的格式是带有2个小数位的浮点数,因此您将使用.2f作为格式说明符:

x = 2606.89579999999
x = round(x, 2)      # not strictly necessary as format will round for you
print(f'{x:.2f}')

输出:

2606.90

5
>>> '{:.2f}'.format(2606.89579999999).replace('.', '')
'260690'

2

我看到的答案没有让我满意,所以这里是我的解决方案:

def round_with_padding(value, round_digits):
    return format(round(value,round_digits), "."+str(round_digits)+"f")

希望您喜欢它


1
如果您想动态更改小数位数,可以使用以下修改:
def formatNumber(n, digits):
    formatter = '{:.' + '{}'.format(digits) + 'f}'
    x = round(n, digits)
    return formatter.format(x)

x = 2606.89579999999
digits = 2

formatted_number = formatNumber(x, digits)

那么,您所需做的就是更改digits变量。这将返回:
2606.90

1
replace n by x, right? - j35t3r
1
@j35t3r,你说得完全正确。我已经编辑了我的回答。 - Vasilis G.

-7
>>> int (round (2606.89579999999,2)*100)
260690

2
不好的想法。>>> int(round(0.29, 2) * 100) -> 28 - Mark Dickinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接