概述
python中有太多对小数得操作,如保留小数位,强制转化为整数等等,其实对于大部分人而言,其中小数位的处理究竟是“四舍五入”或“四舍六入”又或者是“四舍六入五成双”。下面我们来总结一下:
int强制转换
在Python中int强制转化操作是一种“向零舍入”的方式,即需要处理的数字直接舍弃:
print(5.9) # 5
print(-5.9) # -5
这并不是我们所需要的“四舍五入”,如果要实现“四舍五入”,我们可以让其加/减上0.5(正数加0.5,负数减0.5)再进行强制转换:
a = 5.4
b = 5.5
print(int(a + 0.5)) # 5
print(int(b + 0.5)) # 6
print(int(-a - 0.5)) # -5
print(int(-b - 0.5)) # -6
decimal.quantize
decimal
是Python对小数处理非常友好的标准库,decimal
有以下几种舍入模式:
decimal.ROUND_CEILING
: 向正无穷舍入。
# 保留0位小数
a = 5.1
b = 5.9
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_CEILING)) # 6
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_CEILING)) # 6
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_CEILING)) # -5
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_CEILING)) # -5
decimal.ROUND_DOWN
: 向零舍入
# 保留0位小数
a = 5.1
b = 5.9
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_DOWN)) # 5
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_DOWN)) # 5
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_DOWN)) # -5
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_DOWN)) # -5
decimal.ROUND_FLOOR
: 向负无穷舍入
# 保留0位小数
a = 5.1
b = 5.9
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_FLOOR)) # 5
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_FLOOR)) # 5
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_FLOOR)) # -6
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_FLOOR)) # -6
decimal.ROUND_HALF_DOWN
: 五舍六入
# 保留0位小数
a = 5.6
b = 5.5
c = 5.4
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # 6
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # 5
print(Decimal(c).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # 5
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # -6
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # -5
print(Decimal(-c).quantize(Decimal('0'), decimal.ROUND_HALF_DOWN)) # -5
decimal.ROUND_HALF_EVEN
: 四舍六入五成双。即当处理数字为4及以下时将舍弃,6及以上则进位;为中间数字5时,需要看5后面是否还有不为0的任何数字,如果有,则直接进位,然后看前面得数字是奇数则进位,否则则舍弃
# 保留0位小数
a = 4.6
b = 4.5
c = 4.4
d = 5.6
e = 5.5
f = 5.4
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 5
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 4
print(Decimal(c).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 4
print(Decimal(d).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 6
print(Decimal(e).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 6
print(Decimal(f).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # 5
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -5
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -4
print(Decimal(-c).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -4
print(Decimal(-d).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -6
print(Decimal(-e).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -6
print(Decimal(-f).quantize(Decimal('0'), decimal.ROUND_HALF_EVEN)) # -5
decimal.ROUND_HALF_UP
: 四舍五入
# 保留0位小数
a = 5.6
b = 5.5
c = 5.4
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # 6
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # 6
print(Decimal(c).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # 5
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # -6
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # -6
print(Decimal(-c).quantize(Decimal('0'), decimal.ROUND_HALF_UP)) # -5
decimal.ROUND_UP
: 两端舍入(正数向正无穷,负数向负无穷)
# 保留0位小数
a = 5.1
b = 5.9
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_UP)) # 6
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_UP)) # 6
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_UP)) # -6
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_UP)) # -6
decimal.ROUND_05UP
: 零向舍入之后如果最后一位数字位0或5,则进位,否则舍弃
# 保留0位小数
a = 4.6
b = 5.6
print(Decimal(a).quantize(Decimal('0'), decimal.ROUND_05UP)) # 4。4.6零向舍入之后为4,最后一位数字为4,所以舍弃,则为4
print(Decimal(b).quantize(Decimal('0'), decimal.ROUND_05UP)) # 6。5.6零向舍入之后为5,最后一位数字为5,所以进位,则为6
print(Decimal(-a).quantize(Decimal('0'), decimal.ROUND_05UP)) # -4
print(Decimal(-b).quantize(Decimal('0'), decimal.ROUND_05UP)) # -6
%.{num}f
舍入模式为ROUND_HALF_EVEN
(四舍六入五成双),即当处理数字为4及以下时将舍弃,6及以上则进位;为中间数字5时,需要看5后面是否还有不为0的任何数字,如果有,则直接进位,然后看前面得数字是奇数则进位,否则则舍弃。如下:
# 保留0位小数
a = 4.6
b = 4.5
c = 4.4
d = 5.6
e = 5.5
f = 5.4
print('%.0f' % a) # 5
print('%.0f' % b) # 4
print('%.0f' % c) # 4
print('%.0f' % d) # 6
print('%.0f' % e) # 6
print('%.0f' % f) # 5
print('%.0f' % -a) # -5
print('%.0f' % -b) # -4
print('%.0f' % -c) # -4
print('%.0f' % -d) # -6
print('%.0f' % -e) # -6
print('%.0f' % -f) # -5
format
舍入模式为ROUND_HALF_EVEN
(四舍六入五成双),即当处理数字为4及以下时将舍弃,6及以上则进位;为中间数字5时,需要看5后面是否还有不为0的任何数字,如果有,则直接进位,然后看前面得数字是奇数则进位,否则则舍弃。如下:
a = 4.6
b = 4.5
c = 4.4
d = 5.6
e = 5.5
f = 5.4
print(format(a, '.0f')) # 5
print(format(b, '.0f')) # 4
print(format(c, '.0f')) # 4
print(format(d, '.0f')) # 6
print(format(e, '.0f')) # 6
print(format(f, '.0f')) # 5
print(format(-a, '.0f')) # -5
print(format(-b, '.0f')) # -4
print(format(-c, '.0f')) # -4
print(format(-d, '.0f')) # -6
print(format(-e, '.0f')) # -6
print(format(-f, '.0f')) # -5
round
内置函数round
可以帮助我们对小数操作,保留指定小数位。它是ROUND_HALF_EVEN
(四舍六入五成双)舍入模式,即当处理数字为4及以下时将舍弃,6及以上则进位;为中间数字5时,需要看5后面是否还有不为0的任何数字,如果有,则直接进位,然后看前面得数字是奇数则进位,否则则舍弃。如下:
a = 4.6
b = 4.5
c = 4.4
d = 5.6
e = 5.5
f = 5.4
print(round(a, 0)) # 5
print(round(b, 0)) # 4
print(round(c, 0)) # 4
print(round(d, 0)) # 6
print(round(e, 0)) # 6
print(round(f, 0)) # 5
print(round(-a, 0)) # -5
print(round(-b, 0)) # -4
print(round(-c, 0)) # -4
print(round(-d, 0)) # -6
print(round(-e, 0)) # -6
print(round(-f, 0)) # -5
注意事项
值得注意的是,在一些日常开发中,我们使用上面的那些舍入模式,通常会得到意料之外的结果。例如:2.675使用ROUND_HALF_EVEN
、ROUND_HALF_UP
和ROUND_HALF_DOWN
保留2位小数,最后会得到2.67。与我们预想的结果不符,这是因为机器中浮点数不一定能精确表达,因为换算成一串1和0后可能是无限位数的,机器已经做出了截断处理。那么在机器中保存的2.675这个数字就比实际数字要小那么一点点
最后
以上就是懦弱黑裤为你收集整理的你所不知道的“四舍五入”的全部内容,希望文章能够帮你解决你所不知道的“四舍五入”所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复