一、问题说明

以前对浮点数运行没有没有太在意。昨天同事要求把百分比结果保存到文件上,然后就以保存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

https://baike.baidu.com/item/%E5%8D%81%E8%BF%9B%E5%88%B6%E8%BD%AC%E4%BA%8C%E8%BF%9B%E5%88%B6/393189?fr=aladdin

Python3浮点型(float)运算结果不正确处理办法的更多相关文章

  1. JS 浮点型数字运算(转)

    示例: var num1=3.3; var num2=7.17; var ret=parseFloat(num1)+parseFloat(num2); //ret的值为:10.469999999999 ...

  2. 浮点型 float和double类型的内存结构和精度问题

    首先引用一个例子在java中可能你会遇到这样的问题: 例:0.99999999f==1f //true 0.9999999f==1f //false 这是超出精度造成的,为了知道为什么会造成这样的问题 ...

  3. Python3基础-分数运算

    Python3分数运算 fractions 模块可以被用来执行包含分数的数学运算. 案例 >>> from fractions import Fraction >>> ...

  4. php浮点数(float)运算中转整形(int)问题

    今天工作中遇见了一个浮点数转整形的问题,特此记录一下,防止以后再次踩坑. 实例: $f = 0.58; var_dump(intval($f * 100.0)); 也许你认为他会输出58,但是实际上他 ...

  5. Java使用BigDecimal保留double、float运算精度、保留指定位数有效数字、四舍五入

    工具类 package --; import java.math.BigDecimal; /** * Created by kongqw on 2015/12/10. */ public final ...

  6. js float运算精度问题

    先放个前辈的文章:JavaScript数字精度丢失问题总结 今天遇到了19.99*100的问题,答案不等于1999,因为在javascript中浮点数的计算是以2进制计算的.自己写了一波解决方法(不能 ...

  7. Python3基础 ** 幂运算 // 整除运算

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. python3 定义向量运算

    from math import hypot #定义向量的构造方法 class Vector: def __init__(self,x=0,y=0): self.x=x; self.y=y; ''' ...

  9. python float运算时存在浮点误差,结果小数点带.00002及解决方法

    背景: 返回一个json字符串,result结果里面嵌套多个内容一样,只有具体数据不一样的列表[字典],现在需要从里面取指定的key值,来计算最后的总额. 原来使用的类型,float 通过取到json ...

随机推荐

  1. OO第一单元优化博客

    OO第一单元优化博客 第一次作业: 合并同类项+提正系数项+优化系数指数0/1=满分 第二次作业: 初始想法 一开始是想以\(sin(x)​\)和\(cos(x)​\)的指数作为坐标,在图上画出来就可 ...

  2. debugging kubernetes (Delve and Goland)

    1. Build from source cd GOPATH mkdir k8s.io cd k8s.io git clone https://github.com/kubernetes/kubern ...

  3. appium1.4版本,每次运行appium时需要安装unlock,setting文件的解决方法

    在使用appium执行自动化脚本时,首次运行脚本时会在手机中安装unlock,setting,inputmanager三个apk,以达到让appium控制app的目的,但是运行完一次之后,在OPPO, ...

  4. 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛) H XOR

    链接:https://www.nowcoder.com/acm/contest/116/H来源:牛客网 题目描述 Once there was a king called XOR, he had a ...

  5. Extundelete 数据恢复

    Extundelete 数据恢复 “rm -rf /*” 是我们经常使用的命令,操作不慎全盘接蹦,从删库到跑路,身为过来人的我们都经历过rm带来的痛苦. 不要慌,当我们有了Extundelete就可以 ...

  6. 算法(第四版)C# 习题题解——2.5

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更方便的版本见:https ...

  7. C#线程同步(3)- 互斥量 Mutex

    文章原始出处 http://xxinside.blogbus.com/logs/47162540.html 预备知识:C#线程同步(1)- 临界区&Lock,C#线程同步(2)- 临界区&am ...

  8. IIC为什么要配置为开漏输出呢?

    开漏输出只能输出低电平,类似于三极管的集电极,要输出高电平需要上拉电阻才能输出 当集电极接上拉电阻后,(1)基极为高电平,三极管导通,集电极的电位就会被拉低: (2)基极为低电平,三极管不导通,集电极 ...

  9. Largest Rectangular Area in a Histogram 最大连续面积

    在HankerRank遇到一题计算柱状图连续矩形面积的问题. 举例 hist = [3, 2, 3]. 在这个柱状图里面最大可以容纳一个high = 2 length = 3的连续矩形, 其面积 = ...

  10. C语言--第2次作业

    1.本章学习总结 1.1思维导图 1.2本章学习体会及本章代码量 1.2.1学习体会 不同于前几周简单的条件语句等,这一周开始学习循环结构for,while语句,甚至是多种语句嵌套使用,让我直接感受到 ...