可以使用格式对整数进行舍入?

时间:2013-11-07 01:12:31

标签: python

我试图取一个大整数,即:123123123并用3位精度和逗号格式化它。格式可以使用以下命令添加逗号:

'{:,}'.format(123123123)  # '123,123,123'

并指定浮点的精度:

'{0:.2f}'.format(3.141592) # '3.14'

但如果我想同时做两件事呢?

即:

'{:,3d}'.format(123123123)  # ValueError

我想让它返回:123,000,000

2 个答案:

答案 0 :(得分:4)

没有办法直接这样做。 Python整数的重点是它们是无限精度的;如果你想围绕它们,你必须明确地做。事实上,当您尝试显而易见时,异常中的消息告诉您:

>>> '{:,.3d}'.format(123123123)
ValueError: Precision not allowed in integer format specifier

所以,你对此的尝试是直接的......但它不仅仅是一点时髦:

'{:,.0f}'.format(round(123123123,-6))

没有理由明确强制intfloat只是为了让你可以打印它而没有任何小数值。只需让它保持int

'{:,}'.format(round(123123123, -6))

除了更简单之外,这也意味着当你试图有一天打印一个巨大的整数时,它不会给你一个OverflowError或丢失的数字超过你想要的数字......

在早期版本的Python(即2.x)中,round总是返回float,无论你给它什么类型,你都不能这样做;你可能想要写一个简单的intround函数。例如:

def intround(number, ndigits):
    return (number + 5 * 10**(-ndigits-1)) // 10**-ndigits * 10**-ndigits

如果你知道一个事实,你永远不会有一个太大的整数无法无损地融入float,你只能使用int(round(*args)) - 但实际上,如果你可以避免将整数转换为漂浮,你应该。

而且,虽然我们正在使用它,但是当你可以调用自由函数时,没有理由建立一个{}字符串来调用format方法:

format(round(123123123, -6), ',')

答案 1 :(得分:1)

执行此操作的“正确”方法是独立于Python版本(嗯 - 它必须with所以2.5+)使用Decimal模块:

from __future__ import print_function
import decimal
import sys

if sys.version_info.major<3: 
    ic=long
else:
    ic=int    

def ri(i, places=6):
    with decimal.localcontext() as lct:
        lct.prec=places
        n=ic(decimal.Decimal(i,)+decimal.Decimal('0'))
    return format(n,',')

print(ri(2**99, 4)) 
# 633,800,000,000,000,000,000,000,000,000
print(ri(12349159111, 7))    
# 12,349,160,000
print(ri(12349111111, 3))  
# 12,300,000,000

如果使用round method,它在Python 2上相当脆弱:

Python 2:

>>> format(round(12349999999999999,-6),',')
'1.235e+16'    # wrong....

它适用于Python 3,但这是这样做的方式,因此舍入是从左到右:

def rir(i, places=6):
    return format(round(i, places-len(str(i))), ',')

print(rir(2**99, 4))   
# 633,800,000,000,000,000,000,000,000,000
print(rir(12349159111, 7))   
# 12,349,160,000

对于ndigits的负偏移,round(number[, ndigits])将从右到左舍入浮点的尾数:

>>> round(123456789,-4)
123456789123460000

在Python 3上使用更大的数字效果很好:

>>> round(123456789123456789,-8)
123456789100000000

在Python 2上,功能因较大的数字而中断:

>>> round(123456789,-4)
123460000.0
>>> round(123456789123456789,-4)
1.2345678912346e+17

使用十进制模块,它在Python 2和Python 3上按预期工作。