python3 小数位的四舍五入(用两种方法解决round 遇5不进)

 更新时间:2019年04月11日 09:58:42   作者:上海_彭彭  
这篇文章主要介绍了python3 小数位的四舍五入(用两种方法解决round 遇5不进),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

round( )函数简介

菜鸟教程中介绍到,round() 函数作用就是,返回浮点数x的四舍五入值。

> round( x [, n] )

参数x,n均为数值表达式,返回值为x的四舍五入值。n为保留的小数位数,不加n则只保留x四舍五入后的整数部分。

>>> round(2.3)
2
>>> round(2.45, 1)
2.5

特殊情况

上面的结果并没有错误,这里再用2.675测试一下:

>>> round(2.675, 2)
2.67

显然结果不符合四舍五入的规则。为什么会这样呢?原因是:round()函数只有一个参数,不指定位数的时候,返回一个整数,而且是最靠近的整数,类似于四舍五入,当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的情况时,如果要取舍的位数前的小数是奇数,则直接舍弃,如果是偶数则向上取舍。

小数位的四舍五入在项目中经常用到,今天群里有人提出1.325 如何才能变成1.33?

当时我一看这么简单,分秒就可以解决:

我回复是这样的的

round(1.315,2)

有个小伙伴 当时就回复:

他要的结果是 1.32, 你打印出是1.31,我看到我想怎么可能呢,我自己运行下,

结果真是1.31 .

我想都没有想,自认为我是对的,好吧,怪不得开发不能测试自己的代码.

我就开始查找原因,我们通过代码进行讲解:

print(Decimal(1.325))

打印结果:

1.3249999999999999555910790149937383830547332763671875

大家看到了吗? 实际1.325用二进制转化的是有精度损失.部分小数无法完全用二进制表示.
这是根本所在.

那有的同学该说了,为什么 有的五能进1 能解释下原理吗?
原理和上边的一样,我举个例子 5可以进1

print(round(1.145,2))
#打印结果
1.15

继续查看二进制保存的值:

print(Decimal(1.145))
#打印结果 
1.145000000000000017763568394002504646778106689453125

大家明白了吧 ,round 本身没有问题,而是二进制保存的值有点误差导致的.

有的同学该说了 那怎么避免这种错误 。

我准备了两套方案

1.将数值放大100倍,以利用下面的精确的四舍五入的结果`

def round_up(value):
  # 替换内置round函数,实现保留2位小数的精确四舍五入
  return round(value * 100) / 100.0

应用下 看看结果 如何:

def round_up(value):
  # 替换内置round函数,实现保留2位小数的精确四舍五入
  return round(value * 100) / 100.0

print(round(1.4))

print(round(1.5))

print(round_up(1.115))

print(Decimal(1.115))

#打印结果:
1
2
1.12
1.1149999999999999911182158029987476766109466552734375

看着还不错哦,1.115 居然转化成功了.

2.decimal.Decimal

四舍五入是基于十进制的,在二进制无法精确表示的时候是会有误差的。

任何需要十进制运算的地方,都需要用 decimal.Decimal 取代 float:

from _pydecimal import Decimal, Context, ROUND_HALF_UP
print(Context(prec=3, rounding=ROUND_HALF_UP).create_decimal('1.325'))

打印结果:

1.33

自己可以试试其他的值,一定都可以进位.

通过上边的讲解 一定明白 round 本身没有问题,只是float 存储的过程有点误差.

也可以这么解释:

这不是bug,而是一种常见的舍入法,名称是“银行家式舍入法”,

用意是一半舍一半入,如果碰到0.5全入,那么银行觉得自己亏了,

银行希望和用户要风险对半。不光Python,其他的计算机语言都是这个方法,

例如C语言和Basic语言。其实不只是计算机科学,在科学实验的数据处理中,也是采用这种舍入法

推荐第二种方法, 细心的同学可以发现第一种还是不能完成达到5进,自己可以思考下

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

相关文章

  • pandas分组排序 如何获取第二大的数据

    pandas分组排序 如何获取第二大的数据

    这篇文章主要介绍了pandas分组排序 获取第二大的数据的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Python发送网络请求(requests)

    Python发送网络请求(requests)

    这篇文章主要介绍了Python发送网络请求(requests),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Python修改游戏内存的方法

    Python修改游戏内存的方法

    本文给大家分享一个通过Python来修改游戏内存的方法,帮助大家更改游戏中的数据,步骤很简单,而且有视频讲解,感兴趣的朋友一起看看吧
    2021-11-11
  • 浅谈Python数学建模之固定费用问题

    浅谈Python数学建模之固定费用问题

    本文主要介绍了Python固定费用问题的建模与求解。学习 PuLP工具包中处理复杂问题的快捷使用方式
    2021-06-06
  • python协程与 asyncio 库详情

    python协程与 asyncio 库详情

    这篇文章主要介绍了python协程与 asyncio 库详情,文章基于python展开详细内容,具有一定的参考价值。需要的小伙伴可以参考一下
    2022-05-05
  • Python常用的模块和简单用法

    Python常用的模块和简单用法

    这篇文章主要给大家介绍Python#常用的模块和简单用法,以random 随机模块展开话题,感兴趣的小伙伴可以参考一下
    2021-10-10
  • 用python爬取今日说法每期数据

    用python爬取今日说法每期数据

    大家好,本篇文章主要讲的是用python爬取今日说法每期数据,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • 在Mac OS上使用mod_wsgi连接Python与Apache服务器

    在Mac OS上使用mod_wsgi连接Python与Apache服务器

    这篇文章主要介绍了在Mac OS上使用mod_wsgi连接Python与Apache服务器的方法,同时文中还介绍了使用Python的Django框架时mod_wsgi连接方式下可能遇到的问题的一般解决方法,需要的朋友可以参考下
    2015-12-12
  • Python3.8中如何使用print打印变量

    Python3.8中如何使用print打印变量

    这篇文章主要介绍了Python3.8中如何使用print打印变量问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Python实现音频添加数字水印的示例详解

    Python实现音频添加数字水印的示例详解

    数字水印技术可以将隐藏信息嵌入到音频文件中而不明显影响音频质量,下面小编将介绍几种在Python中实现音频数字水印的方法,希望对大家有所帮助
    2025-04-04

最新评论