我是靠谱客的博主 懦弱黑裤,最近开发中收集的这篇文章主要介绍你所不知道的“四舍五入”,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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_EVENROUND_HALF_UPROUND_HALF_DOWN保留2位小数,最后会得到2.67。与我们预想的结果不符,这是因为机器中浮点数不一定能精确表达,因为换算成一串1和0后可能是无限位数的,机器已经做出了截断处理。那么在机器中保存的2.675这个数字就比实际数字要小那么一点点

最后

以上就是懦弱黑裤为你收集整理的你所不知道的“四舍五入”的全部内容,希望文章能够帮你解决你所不知道的“四舍五入”所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部