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

 更新时间:2020年09月22日 14:38:15   作者:诸子流  
这篇文章主要介绍了Python浮点型(float)运算结果不正确的解决方案,帮助大家更好的利用python进行运算处理,感兴趣的朋友可以了解下

一、问题说明

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

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

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

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

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

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

二、原因探究

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

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

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

可能有人会疑惑:为什么二进制可以表示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本质应该还是通过加长长度提高精度)

# 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)}%"

参考:

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

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

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

相关文章

  • Python range函数生成一系列连续整数的内部机制解析

    Python range函数生成一系列连续整数的内部机制解析

    这篇文章主要为大家介绍了Python range函数生成一系列连续整数的内部机制解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • pyinstaller打包路径的总结

    pyinstaller打包路径的总结

    本文主要介绍了pyinstaller打包路径的总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 数据清洗之如何用一行Python代码去掉文本中的各种符号

    数据清洗之如何用一行Python代码去掉文本中的各种符号

    我们在处理文本的时候往往需要对标点符号进行处理,下面这篇文章主要给大家介绍了关于数据清洗之如何用一行Python代码去掉文本中的各种符号的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • TensorFlow2.0:张量的合并与分割实例

    TensorFlow2.0:张量的合并与分割实例

    今天小编就为大家分享一篇TensorFlow2.0:张量的合并与分割实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • python实现通讯录系统

    python实现通讯录系统

    这篇文章主要为大家详细介绍了python实现通讯录系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • python-parser.parse_args()解析参数问题

    python-parser.parse_args()解析参数问题

    这篇文章主要介绍了python-parser.parse_args()解析参数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 如何使用python提取字符串的中英文(正则判断)

    如何使用python提取字符串的中英文(正则判断)

    这篇文章主要给大家介绍了关于如何使用python提取字符串中英文的相关资料,主要通过正则re中的sub函数、findall函数以及compile函数判断来实现,需要的朋友可以参考下
    2021-05-05
  • python实现支持目录FTP上传下载文件的方法

    python实现支持目录FTP上传下载文件的方法

    这篇文章主要介绍了python实现支持目录FTP上传下载文件的方法,适用于windows及Linux平台FTP传输文件及文件夹,需要的朋友可以参考下
    2015-06-06
  • Python游戏开发实例之graphics实现AI五子棋

    Python游戏开发实例之graphics实现AI五子棋

    五子棋是经典的棋牌类游戏,很多人都玩过,那么如何用Python实现五子棋呢,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 解决python路径错误,运行.py文件,找不到路径的问题

    解决python路径错误,运行.py文件,找不到路径的问题

    这篇文章主要介绍了解决python路径错误,运行.py文件,找不到路径的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03

最新评论