Python浮点型(float)运算结果不正确的解决方案


Posted in Python onSeptember 22, 2020

一、问题说明

以前对浮点数运行没有没有太在意。昨天同事要求把百分比结果保存到文件上,然后就以保存1位小数的形式给他保存了。

但是今天同事运行时问能不能统一以一位小数的形式保存,当时觉得很奇怪昨天就是以一位小数形式存的怎么还会提这种要求呢。

其给回的截图确实是部分是一位小数的,但一部分是很长的。查看代码都统一如下格式:

# 使用round保留三位小数,然后乘以100,最后格式化为带百分号的字符串
rate=f"{round(x/y,3) * 100}%"

代码上没看出什么问题,直接运行确实是有些结果是一长串的。进行调试发现当x为37y为76时即会出现问题,如下图所示:

Python浮点型(float)运算结果不正确的解决方案

进行步骤拆分,发现round方法没有问题,问题在浮点数乘以100上(同时如下图可以看到也不是所有浮点数乘都有问题)

Python浮点型(float)运算结果不正确的解决方案

二、原因探究

搞不清原因,直到看到这篇文章:https://www.programiz.com/python-programming/numbers

大意是说二进制对很多浮点数无法准确表示只能用一个近似值代替,而当使用这些以近似值代替的浮点数进行进算时本质上是这些进似值参与了运算,出来的结果也就是进似值运算后的结果。

也就是说,一是这不是乘100的问题也不是乘法的问题而是整个浮点数运算都有问题,二是这不是python的问题是计算机浮点数存储的问题像C、Java等其他计算机语言进行运算都会有问题。

Python浮点型(float)运算结果不正确的解决方案

可能有人会疑惑:为什么二进制可以表示2不能表示0.2呢?

这是因为数值和字符串是不一样的,如果是字符串那么表示2.2点的左右两边的2编码是一样的就可以了(如ASCII码:504650),但数值不是这样,数值的整数部分和小数部分需要一个统一的表示形式,那就是加权位计数法。

整数部分都要以2的0次方(20)到2的无穷次方(2∞)表示,这没有问题,只要长度足够就能表示出所有奇数和偶数。2 = 1 * 21 + 0 * 20 = 10

小数部分都要以2的-1次方(2-1)到2的负无穷次方(2-∞)表示,这就有问题,因为比如2-1...2-∞不管怎么组合都不能完全等于0.2。0.2 = 0 * 2-1 + 0 * 2-2 + 1 * 2-3 ...

三、处理办法

这情况让我想起上份工作局方领导的一句话,应该是“可以理解但不能接受”。

原理上二进制无法精确表示一些浮点数可以理解,但是就这么返回个显然错误的结果给用户那是无法接受的。

python提供了Decimal()方法让浮点运算结果可以和人平时运算的结果一样。(Decimal本质应该还是通过加长长度提高精度)

Python浮点型(float)运算结果不正确的解决方案

# Decimal传字符串才能准确表示,所以需要先用str()把round()的结果转为字符串
rate=f"{Decimal(str(round(x/y,3))) * 100}%"

# 其实上边的结果出来是48.700%的形式,即三位小数的形式并不太符合我们保留一位小数的想法,真正符合想法得下面这样
# rate=f"{round(Decimal(str(round(x/y,3))) * 100, 1)}%"

# 其实我们说了这么多,我们都是建立在决定保留多少位再乘100这个前提下,倘若我们先乘100后决定保留几位那都不需要用Decimal
# rate=f"{round(x/y*100,1)}%"

Python浮点型(float)运算结果不正确的解决方案

参考:

https://www.programiz.com/python-programming/numbers

https://docs.python.org/3.7/library/decimal.html

以上就是Python浮点型(float)运算结果不正确的解决方案的详细内容,更多关于Python浮点型(float)运算结果不正确的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python中类的继承代码实例
Oct 28 Python
Python中pow()和math.pow()函数用法示例
Feb 11 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
Dec 13 Python
基于python+selenium的二次封装的实现
Jan 06 Python
Python *args和**kwargs用法实例解析
Mar 02 Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
Mar 10 Python
Python利用命名空间解析XML文档
Aug 10 Python
python利用xlsxwriter模块 操作 Excel
Oct 14 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
Oct 15 Python
安装pytorch时报sslerror错误的解决方案
May 17 Python
Pytorch使用shuffle打乱数据的操作
May 20 Python
pytorch通过训练结果的复现设置随机种子
Jun 01 Python
如何使用PyCharm引入需要使用的包的方法
Sep 22 #Python
python 如何区分return和yield
Sep 22 #Python
Python中三维坐标空间绘制的实现
Sep 22 #Python
Pyinstaller打包Scrapy项目的实现步骤
Sep 22 #Python
Python使用pickle进行序列化和反序列化的示例代码
Sep 22 #Python
Python如何获取文件路径/目录
Sep 22 #Python
JupyterNotebook 输出窗口的显示效果调整实现
Sep 22 #Python
You might like
PHP学习之PHP运算符
2006/10/09 PHP
php 服务器调试 Zend Debugger 的安装教程
2009/09/25 PHP
php join函数应用
2011/05/04 PHP
限制ckeditor上传图片文件大小的方法
2013/11/15 PHP
php中实现精确设置session过期时间的方法
2014/07/17 PHP
Gambit vs CL BO3 第二场 2.13
2021/03/10 DOTA
Javascript中的this绑定介绍
2011/09/22 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
2013/07/01 Javascript
jQuery.parseJSON(json)将JSON字符串转换成js对象
2014/07/27 Javascript
JS跨域问题详解
2014/11/25 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
2015/07/29 Javascript
javascript与Python快速排序实例对比
2015/08/10 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
Jquery+Ajax+xml实现中国地区选择三级联动菜单效果(推荐)
2017/06/09 jQuery
Vue.js学习笔记之修饰符详解
2017/07/25 Javascript
原生javascript实现的全屏滚动功能示例
2017/09/19 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
解决layui中table异步数据请求不支持自定义返回数据格式的问题
2018/08/19 Javascript
浅谈微信小程序flex布局基础
2018/09/10 Javascript
JS 实现发送短信验证码的“59秒后重新发送验证短信”功能
2019/08/23 Javascript
[44:10]2018DOTA2亚洲邀请赛 4.5 淘汰赛 EG vs VP 第一场
2018/04/06 DOTA
[03:02]2020完美世界城市挑战赛(秋季赛)总决赛回顾
2021/03/11 DOTA
Python中对元组和列表按条件进行排序的方法示例
2015/11/10 Python
python模块之subprocess模块级方法的使用
2019/03/26 Python
Python使用微信接入图灵机器人过程解析
2019/11/04 Python
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
车间调度岗位职责
2013/11/30 职场文书
大学新闻系应届生求职信
2014/06/02 职场文书
公司任命书范本
2014/06/04 职场文书
体育教育毕业生自荐信
2014/06/29 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
2015年秋季小班开学寄语
2015/05/27 职场文书
《纸船和风筝》教学反思
2016/02/18 职场文书
Python 内置函数速查表一览
2021/06/02 Python
使用CSS实现小三角边框原理解析
2021/11/07 HTML / CSS