解决Python中的modf()函数取小数部分不准确问题
作者:可乐味的鼻涕 发布时间:2023-06-12 06:24:43
使用math.modf()对一个浮点数进行拆分时经常会遇到如下情况
如下
import math
print(math.modf(2.4)) # 输出 (0.3999999999999999, 2.0)
我们会发现对2.4进行拆分得到的小数并不是0.4,这是因为什么呢?
这是因为计算机采用的是二进制代码,而二进制代码由于计算上的误差无法准确表示某些十进制数的小数部分。
下面我们具体来讲一下。
我们知道一个十进制数转化为二进制数需要分为两部分进行计算:整数部分和小数部分。
整数部分采用“除二取余法”。将这个整数除以2,得到它的余数,然后将商再除以3,直到商为0为止,并将各个得到的余数按照相反的顺序进行排列。
小数部分采用“乘2取整法”,将这个小数乘2,将新得到的数的整数部分取出,再用2乘余下的小数部分,如此往复直到乘积中的小数部分为0或者达到要求的精度为止。并将取出的整数部分按照取出的先后顺序从前到后排列。
123/2=61...1
61/2=30...1
30/2=15...0
15/2=7...1
7/2=3...1
3/2=1...1
1/2=0...1
(123)10=(1111011)2
0.4*2=0.8...0
0.8*2=1.6...1
0.6*2=1.2...1
0.2*2=0.4...0
0.4*2=0.8...0
0.8*2=1.6...1
0.6*2=1.2...1
(0.4)10=(0.011001100110011001100110...)2
(123.4)2=(1111011.011001100110011...)2
十进制的0.4转化为二进制时会出现重复循环“0110”的情况,但是目前计算机存储浮点数是按照电器和电子工程师协会的标准(IEEE754浮点数存储格式标准)来进行存储的。
IEEE规定单精度浮点最多存储32位(4个字节):
31位是符号位。1表示该数为负,0为正
30~23是指数位(-128-127)
22~0是尾数位,尾数的编码一般是源码和补码
IEEE标准从逻辑上用三元组{S,E,M}表示一个数,如图所示:
也就是说上面将0.4转换出的二进制代码,我们只能存储23位,即使数据类型为double,也只能存储52位,这样大家便能看出问题出现的原因了。23位的数据显然无法完整表示0.4的二进制数据,于是误差产生了。
那所有的十进制小数都无法完整表示吗?不是的,只要小数部分乘上2最终小数部分能够得到0就不会出现这种问题,比如0.5,0.75。
import math
print(math.modf(1.5)) # 输出 (0.5,1.0)
0.5*2=1...1
(0.5)10=(0.1)2
0.75*2=1.5...1
0.5*2=1...1
(0.75)10=(0.11)2
补充:Python中“取整”的各种问题
一、初衷:
有时候我们分页展示数据的时候,需要计算页数。一般都是向上取整,例如counts=205 pageCouts=20 ,pages= 11 页。
一般的除法只是取整数部分,达不到要求。
二、方法:
1、通用除法:
UP(A/B) = int((A+B-1)/B)
取临界值,计算下A+B-1的范围就OK.
2 、Python除法:
首先要说的是python中的除法运算,
当使用x/y形式进行除法运算时,那么会进行所谓的true除法,比如2.0/3的结果是 0.66666666666666663。
另外一种除法是采用x//y的形式(向下取整),那么这里采用的是所谓floor除法,即得到不大于结果的最大整数值,这个运算时与操作数无关的。比如2//3的结果是0,-2//3的结果是-1,-2.0//3的结果是-1.0。
在python 3.0中,x/y将只执行true除法,而与操作数无关;x//y则执行floor除法。
Python运算向上取整方法:(A+B-1)/B
3、Python match.ceil函数 np.ceil函数
ceil(x)函数是向上取整,即取大于等于x的最接近整数。
import math
math.ceil(float(205)/20)
import numpy as np
np.ceil(float(205)/20)
Python 向上取整的算法
1、一般使用floor除法 (np.floor()或者math.floor())
import numpy as np
n = np.array([-1.7, -2.5, -0.2, 0.6, 1.2, 2.7, 11])
floor = np.floor(n)
print(floor) # [ -2. -3. -1. 0. 1. 2. 11.]
2、一般除法/
A=100
B=16
c=100//16
(c=6)
3、round()四舍五入函数。
np.around 返回四舍五入后的值,可指定精度。
around(a, decimals=0, out=None)
a 输入数组
decimals 要舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
import numpy as np
n = np.array([-0.746, 4.6, 9.4, 7.447, 10.455, 11.555])
around1 = np.around(n)
print(around1) # [ -1. 5. 9. 7. 10. 12.]
around2 = np.around(n, decimals=1)
print(around2) # [ -0.7 4.6 9.4 7.4 10.5 11.6]
around3 = np.around(n, decimals=-1)
print(around3) # [ -0. 0. 10. 10. 10. 10.]
Python 分别取整的算法
math模块中的 modf()方法
将整数部分和小数部分分别取出,可以使用math模块中的 modf()方法
例如:
>>> math.modf(4.25)
(0.25, 4.0)
>>> math.modf(4.33)
来源:https://blog.csdn.net/qq_32681043/article/details/103254745


猜你喜欢
- 前言许多任务程序如果为其构造为一个命令行界面,就可以通过接受不同的参数来改变它的工作方式。例如,在爬虫程序中,不同 URL&nbs
- 提高SQL执行效率的几点建议:◆尽量不要在where中包含子查询;关于时间的查询,尽量不要写成:where to_char(dif_date
- 最近做某项目的数据库分析,要实现对海量数据的导入问题,就是最多把200万条数据一次导入sqlserver中,如果使用普通的insert语句进
- 本文实例讲述了通过 jQuery EasyUI框架创建一个RSS阅读器,分享给大家供大家参考。具体如下:运行效果截图如下:我们将使用以下插件
- 在使用django restframework serializer 序列化在django中定义的model时,有时候我们需要额外在seri
- <script language="javascript"><!-- var&n
- 其所用项目由Asp.Net技术开发,仍然使用的Webform作为前端处理,但某些功能包含了jQuery的功能,他遇到的问题就是无论用IE还是
- 原文:http://research.microsoft.com/~helenw/papers/subspace.pdfwindow.nam
- 本文实例讲述了ES6 Promise对象的应用。分享给大家供大家参考,具体如下:The Promise object represents
- 我们知道,全局临时表的生命周期一直持续到创建会话(不是创建级别)才终止。有时候,你可能想创建一个不属于任何会话的全局临时表。而无论你进行什么
- 参考网址 https://www.jb51.net/article/29551.htmSELECT [StartDate] FROM [db
- Oracle 的正规表达式的实施是以各种 SQL 函数和一个 WHERE 子句操作符的形式出现的。如果您不熟悉正规表达式,那么这篇文章可以让
- 今天开始学习Python时发现Pycharm竟然过期了需要重新注册,穷苦学生没钱只能再找找百度了浪费了半天时间终于找到一个可以使用的了,支持
- IIf 函数 根据表达式的值,来返回两部分中的其中一个。语法IIf(expr, truepart, fal
- Pythond 的函数是由一个新的语句编写,即def,def是可执行的语句--函数并不存在,直到Python运行了def后才存在。函数是通过
- 目录前言全局锁表级锁表锁元数据锁(Metadata Locking,简称:MDL锁)总结参考资料前言在真实的企业开发环境中使用MySQL,M
- matplotlib中的字体文件被封装在font_manager这个子模块中,fontManager.ttflist这个列表涵盖了所有Mat
- MySQL当url连接不指定/数据库名可以访问到mysql服务器上有权限的任何库,但是所有sql需要加上库名前缀.pom<depend
- 1、转化成时间格式seconds =35400m, s = divmod(seconds, 60)h, m = divmod(m, 60)p
- 本文介绍了用python与文件进行交互的方法,分享给大家,具体如下:一.文件处理1.介绍计算机系统:计算机硬件,操作系统,应用程序应用程序无