我正在使用这段代码:
f = 0.3223322
float('%.2f' % (f))
有没有更加Pythonic且不那么冗长的方法可以避免两次转换?
使用round函数在文档中有如下说明,这使得它并不受欢迎:
对于浮点数,round()函数的行为可能会令人惊讶:例如,round(2.675, 2)的结果是2.67而不是期望的2.68。这不是一个错误,而是由于大多数十进制小数无法被精确表示为浮点数所导致的结果。有关更多信息,请参见浮点运算:问题和限制。
我正在使用这段代码:
f = 0.3223322
float('%.2f' % (f))
对于浮点数,round()函数的行为可能会令人惊讶:例如,round(2.675, 2)的结果是2.67而不是期望的2.68。这不是一个错误,而是由于大多数十进制小数无法被精确表示为浮点数所导致的结果。有关更多信息,请参见浮点运算:问题和限制。
>>> round(0.3223322, 2)
0.32
请注意,由于浮点数不精确性,产生输出时您可能仍需要使用一定的字符串格式化精度。
根据您要实现的目标,使用Decimal
类型可能是合适的:
>>> from decimal import Decimal
>>> round(Decimal(0.3223322), 2)
Decimal('0.32')
这种方法的计算使用十进制而不是二进制,因此在十进制四舍五入方面没有任何问题(除非您尝试从浮点数创建它时最初出现问题)。
这并不是很好,但我一直是它的粉丝:
f=float(int(100*f))/100
虽然不是最佳的做法,但这是我经常使用的一种方法。
我会选择使用round()
函数,但如果你不喜欢它的行为,你可以自己编写round()
函数,为了完整起见:
def custom_round(number, ndigits=2):
return int(number * 10 ** ndigits) / 10.0 ** ndigits if ndigits else int(number)
请注意,与内置的round()
函数不同,此次舍入将向下取整,而非向上。
您可以使用带有量化和舍入的十进制数。ROUND_HALF_UP是一种数学舍入。
from decimal import Decimal, ROUND_HALF_UP
>>> Decimal('123.527').quantize(Decimal('.01'), rounding=ROUND_HALF_UP)
Decimal('123.53')
>>> Decimal('123.525').quantize(Decimal('.01'), rounding=ROUND_HALF_UP)
Decimal('123.53')
float('%.2f' % f)
和round()
存在完全相同的问题。这是因为,正如文档所述,这是计算机浮点数工作方式的限制。在大多数情况下,我不会太担心它。如果确实有影响,我认为最好使用decimal
模块、fractions
模块或某个任意精度库,具体取决于实际用例。 - Roel Schroeven