Python中round函数使用注意事项

栏目: Python · 发布时间: 5年前

内容简介:使用round函数的时候发现了一个奇怪的现象。一直觉得round函数是一个用于四舍五入的函数,结果却不一定。一般如果觉得奇怪,那就是没弄懂其本质的运作原理,所以深入了解了下round函数。Python版本问题Python2和Python3有很多实现细节上的不同,round函数是其中不同之一。在Python3中,round(1.0/2.0)得到的是1,而在Python2中,round(1.0/2.0)得到的是0

使用round函数的时候发现了一个奇怪的现象。一直觉得round函数是一个用于四舍五入的函数,结果却不一定。一般如果觉得奇怪,那就是没弄懂其本质的运作原理,所以深入了解了下round函数。

Python版本问题

Python2和 Python 3有很多实现细节上的不同,round函数是其中不同之一。在Python3中,round(1.0/2.0)得到的是1,而在Python2中,round(1.0/2.0)得到的是0

貌似Python2之间的不同版本也不同。

Python 2.7:

>>> round(10/3, 2)

3.0

>>> round(0.5)

1.0

>>> round(-0.5)

-1.0

>>> round(1.5)

2.0

如图:

Python中round函数使用注意事项

Python 2.7中:保留值将保留到离上一位更近的一端(四舍六入),如果距离两端一样远,则保留到离0远的一边。所以round(0.5)会近似到1,而round(-0.5)会近似到-1。

Python 3.6:

>>> round(10/3, 2)

3.33

>>> round(0.5)

0

>>> round(-0.5)

0

>>> round(1.5)

2

>>> round(3.5, 2)

3.5  # 不是3.50

如下图:

Python中round函数使用注意事项

Python 3中:如果距离两边一样远,会保留到偶数的一边。比如round(0.5)和round(-0.5)都会保留到0,而round(1.5)会保留到2。

注意上面的对比结果,小数位的位数也有区别的!

计算机表示精度的影响

round函数对于返回的浮点数并不是按照四舍五入的规则来计算,而受收到计算机表示精度的影响。

浮点数的一个普遍问题是它们并不能精确的表示十进制数。 并且,即使是最简单的数学运算也会产生小的误差,比如:

>>> a = 4.2

>>> b = 2.1

>>> a + b

6.300000000000001

>>> a + b == 6.3

False

Python中round函数使用注意事项

Python 2.7 和 3.6:

>>> round(1.675, 2)

1.68

>>> round(2.675, 2)

2.67

Python中round函数使用注意事项

不论我们从python2还是3来看,结果都应该是2.68的,结果它偏偏是2.67,为什么?这跟浮点数的精度有关。我们知道在机器中浮点数不一定能精确表达,因为换算成一串1和0后可能是无限位数的,机器已经做出了截断处理。那么在机器中保存的2.675这个数字就比实际数字要小那么一点点。这一点点就导致了它离2.67要更近一点点,所以保留两位小数时就近似到了2.67。

综上,利用round函数来实现四舍五入和小数位保留,结果可能不是预期的,如果对四舍五入和小数位精度要求高,避免使用round函数。较好的解决方案可以使用decimal模块。

>>> from decimal import Decimal

>>> a = Decimal('4.2')

>>> b = Decimal('2.1')

>>> a + b

Decimal('6.3')

>>> a + b == Decimal('6.3')

True

Python中round函数使用注意事项

>>> from decimal import Decimal

>>> d = Decimal(2.675)  # 如果Decimal参数是浮点数 默认还是会截断

>>> d.quantize(Decimal('0.00'))

Decimal('2.67')

>>> d = Decimal('2.675')  # 用字符串就可以做到正常的四舍五入和精确的精度

>>> d.quantize(Decimal('0.00'))

Decimal('2.68')

>>> d = Decimal(3.5)

>>> d.quantize(Decimal('0.00'))

Decimal('3.50')

>>> d = Decimal('3.5')

>>> d.quantize(Decimal('0.00'))

Decimal('3.50')

Python中round函数使用注意事项

>>> from decimal import Decimal, ROUND_UP

>>> n = Decimal('0.0000416')

>>> n.quantize(Decimal('0.01'))

Decimal('0.00')

>>> n.quantize(Decimal('0.01'), rounding=ROUND_UP) # 保证最小是0.01

Decimal('0.01')

Python中round函数使用注意事项

要处理更精确的分数精度,可以使用fractions模块的Fraction类。

更多Python相关信息见 Python 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=17

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-01/156541.htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创业无畏

创业无畏

彼得· 戴曼迪斯、史蒂芬· 科特勒 / 贾拥民 / 浙江人民出版社 / 2015-8 / 69.90元

 您是否有最大胆的商业梦想?您是否想把一个好主意快速转化为一家市值几百亿甚至几千亿元的公司?《创业无畏》不仅分享了成功创业家的真知灼见,更为我们绘制了一幅激情创业的行动路线图!  创业缺人手怎么办?如何解决钱的问题?把握指数型大众工具,互联网就是你车间,你的仓库。拥有好的创意,自然有人把钱“白白地送给你用”。当你大海捞针的时候,激励性大奖赛会让针自己跑到你的眼前来!  掌握指数级......一起来看看 《创业无畏》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换