网易首页 > 网易号 > 正文 申请入驻

在Python里想要四舍五入有多麻烦?

0
分享至

大家好,欢迎来到 Crossin的编程教室~

四舍五入」是小学就学过的数学知识,也是日常计算中经常会用到的处理方法。

然而让人没想到的是,一个简单的四舍五入操作,在Python里居然这么难搞,网上还一堆错误的教程。

来看这个例子,有一个变量a为1.135,现在希望把它保留2位小数,要怎么做?

网上搜索一下,找到两种方法:

第1种,round函数。第一个参数是原数字,第二个参数是要保留的小数位数


round(a, 2)

结果 1.14,没有问题。

第2种,通过格式说明符.f对浮点数进行字符串格式化,f前加上要保留的小数位数。

这种写法在 %格式化、format方法和f-string 上均适用。


print('%.2f' % a, '{:.2f}'.format(a), f'{a:.2f}')

结果 1.14,也没有问题。

所以看来,以上两种方法都可以实现四舍五入地保留小数位数……


but,真的是这样吗?

显然事情没这么简单。如果把a的值改成1.125,再跑一下之前的代码,就发现两种方法都不对了。


别小看这么一点误差,我曾经在做助教时,就因为类似的原因,导致一位原本算好被60分放过的同学挂了科。


有些不靠谱的半瓶水教程会跟你说,这是因为Python用了种叫做「四舍六入五成双」的保留机制:5前面的数字是奇数就进位,是偶数就保持不变,所以1.135会得到1.14,而1.125就是1.12。


还有的教程告诉你有种方法可以实现四舍五入:就是把要保留N位的小数,乘以10的N次方,加上0.5后取整,再除以10的N次方


int(a * 10 ** 2 + 0.5) / 10 ** 2)

结果确实是 1.13。

但你以为这样就可以了吗?

如果再把a改成1.035。结果既没有什么所谓的奇数进位,也没能通过先乘再除的方法实现四舍五入。


把1.005,1.015,1.025,一直到1.995,用前面提到过的3种方法保留2位小数的结果输出出来就会发现。round和字符串格式化得到的保留结果是一样的,且基本没有规律可言。

而先乘后除法虽然在大部分情况下是符合四舍五入的,但仍然有一些例外的情况。




导致这种现象的原因,和之前讲解过的 一样,都是因为浮点数的精度造成的。

让这些小数输出更多位数,就会看到,很多值虽然结尾是5,但在计算机中以二进制存储的实际值其实不到5。那么按照四舍五入来说,当然是要被舍去了。


真正可以做到对小数保留位数进行精确控制的方法是使用 Python 内置的 decimal 模块,它用于高精度的十进制算术运算。

用 round 函数对于 Decimal 类型对象进行保留,才是真正的四舍六入五成双。


from decimal import Decimal x = 1.035 print(round(Decimal(str(x)), 2))


这种机制又被称作「银行家舍入」,它其实比四舍五入更合理。因为5是两个数的中间值,全都进位会让数据在整体分布上偏大,而银行家舍入规则可以让累积误差趋向于0。

如果你就是想要按照四舍五入来保留,也可以,通过将 Context 里的 rounding 属性设置为 ROUND_HALF_UP 就可以


from decimal import Decimal, ROUND_HALF_UP, getcontext x = 1.045 getcontext().rounding = ROUND_HALF_UP print(round(Decimal(str(x)), 2))

另一种写法是通过 Decimal 的 quantize 方法,指定保留位数和舍入规则,效果是一样的。


from decimal import Decimal x = 1.045 print(Decimal(str(x)).quantize(Decimal('0.01'), rounding='ROUND_HALF_UP'))

这样,就能完美地按四舍五入保留小数了。

不过这里还有一个小小的坑,就是一定要通过字符串去创建 Decimal 对象,否则实际值仍然是带有误差的,从而导致四舍五入失效。


好吧,没想到一个简单的四舍五入操作,竟然还这么复杂,你学会了吗?

作者:Crossin的编程教室

Crossin的新书《码上行动:用ChatGPT学会Python编程》已经上市了。 本书以ChatGPT为辅助,系统全面地讲解了如何掌握Python编程,适合Python零基础入门的读者学习。

购买后可加入读者交流群,Crossin为你开启陪读模式,解答你在阅读本书时的一切疑问。

添加微信 crossin123 ,加入编程教室共同学习 ~


感谢 转发点赞 的各位~

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
当代嫪毐:养8名情妇,坐牢自由进出监狱,靠身体征服女狱警当性奴

当代嫪毐:养8名情妇,坐牢自由进出监狱,靠身体征服女狱警当性奴

古今档案
2023-12-24 22:33:08
A股:大家要提前做好准备,A股很可能会出现更大级别的大涨?

A股:大家要提前做好准备,A股很可能会出现更大级别的大涨?

财经大拿
2024-04-29 01:35:03
53岁男子,同房时发生“性猝死”,提醒:中老年人办事时避免5事

53岁男子,同房时发生“性猝死”,提醒:中老年人办事时避免5事

肿瘤的真相与误区
2024-04-27 19:43:44
回顾:男子在民政局门口捡漏,一见到离婚女人就问:要不结个婚?

回顾:男子在民政局门口捡漏,一见到离婚女人就问:要不结个婚?

佑宛故事汇
2024-04-27 16:19:17
恶战打响,以军突然斩杀两位司令,自家指挥部反遭偷袭死伤惨烈

恶战打响,以军突然斩杀两位司令,自家指挥部反遭偷袭死伤惨烈

复杂说历史
2024-04-27 11:17:53
马自达:当我再努力也无法被中国市场青睐时,就只能选择躺平了

马自达:当我再努力也无法被中国市场青睐时,就只能选择躺平了

前沿科技学习分享圈
2024-04-26 23:13:00
天津市这次有福了,被知名巨擘砸中了3个项目,早知道早下手!

天津市这次有福了,被知名巨擘砸中了3个项目,早知道早下手!

搞笑的阿票
2024-04-28 15:06:31
4月28日,孙俪的在社交平台高调爆料,邓超,万万没想到吧!

4月28日,孙俪的在社交平台高调爆料,邓超,万万没想到吧!

紫雨说娱乐
2024-04-28 19:27:32
分不清大小王?俄要办金砖国家运动会,国际奥委会:谁去就制裁谁

分不清大小王?俄要办金砖国家运动会,国际奥委会:谁去就制裁谁

忠诚TALK
2024-04-28 14:21:51
马筱梅正式宣战大S,与汪小菲恩爱秀不停,张兰态度亮了

马筱梅正式宣战大S,与汪小菲恩爱秀不停,张兰态度亮了

娱记掌柜
2024-04-27 17:26:31
最新“国家卓越工程师学院”建设高校名单:24所顶级工科大学入选

最新“国家卓越工程师学院”建设高校名单:24所顶级工科大学入选

亿通电子游戏
2024-04-28 20:38:30
具俊晔为了躲避张兰,带着妈妈连夜飞台,大S要和婆婆同住了?

具俊晔为了躲避张兰,带着妈妈连夜飞台,大S要和婆婆同住了?

娱乐圈酸柠檬
2024-04-27 21:51:55
我参军退伍前夕救了一个人,竟然给我的人生带来大转变

我参军退伍前夕救了一个人,竟然给我的人生带来大转变

玉玉
2024-02-05 18:11:11
终于压不住!问届M7事故烧死儿子弟弟+老公摔死引全网暴怒!

终于压不住!问届M7事故烧死儿子弟弟+老公摔死引全网暴怒!

魔都囡
2024-04-29 01:32:06
广西一女副校长与校长吵架,因随口说出9个字,生命葬送在38岁

广西一女副校长与校长吵架,因随口说出9个字,生命葬送在38岁

莉雅细细谈
2024-04-08 22:28:38
工地小卖部的老板娘,是个三十多岁的少妇

工地小卖部的老板娘,是个三十多岁的少妇

木木木木林
2024-04-16 11:03:46
浪姐朱丹的新造型真的让人眼前一亮啊,瞬间get到她的颜值了!

浪姐朱丹的新造型真的让人眼前一亮啊,瞬间get到她的颜值了!

娱乐圈酸柠檬
2024-04-29 01:44:38
1940年炊事员在朱德饭里下毒,枪毙之时,杨奇清提出:重审此案

1940年炊事员在朱德饭里下毒,枪毙之时,杨奇清提出:重审此案

我是斌哥哥
2024-04-28 19:24:10
技不如人?为何我国返回舱着陆后一身焦黑,印度返回舱却非常干净

技不如人?为何我国返回舱着陆后一身焦黑,印度返回舱却非常干净

说天说地说实事
2024-04-27 16:43:57
球衣的秘密:国旗当中没有蓝色元素,意大利的主场球衣为什么选用蓝色?

球衣的秘密:国旗当中没有蓝色元素,意大利的主场球衣为什么选用蓝色?

98弗兰德
2024-04-27 07:01:50
2024-04-29 03:38:44
Crossin的编程教室
Crossin的编程教室
简单有趣的python入门
380文章数 702关注度
往期回顾 全部

科技要闻

特斯拉生死时速,马斯克西天取经

头条要闻

警方通报女子在卫生间被打:4人被行拘13日罚款1千元

头条要闻

警方通报女子在卫生间被打:4人被行拘13日罚款1千元

体育要闻

湖人的G4,尽人事得到了回报

娱乐要闻

张杰谢娜发文为何炅庆生,亲如家人!

财经要闻

上财万字报告深度解读Q1经济

汽车要闻

鸿蒙首款行政旗舰轿车 华为享界S9实车亮相车展

态度原创

健康
时尚
家居
手机
艺术

春天野菜不知不识莫乱吃

裤子+小猫跟,这个组合气质又好看

家居要闻

光影之间 空间暖意打造生活律动

手机要闻

OPPO Reno12系列再次被确认:物料已在准备,超大杯疑似被砍!

艺术要闻

共度北京108小时 北京当代2024“凝聚”全球36座城市100余家艺术机构

无障碍浏览 进入关怀版