解决Python中的modf()函数取小数部分不准确问题


Posted in Python onMay 28, 2021

使用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}表示一个数,如图所示:

解决Python中的modf()函数取小数部分不准确问题

也就是说上面将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)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Web框架Flask信号机制(signals)介绍
Jan 01 Python
Python之os操作方法(详解)
Jun 15 Python
pandas使用get_dummies进行one-hot编码的方法
Jul 10 Python
Python二进制串转换为通用字符串的方法
Jul 23 Python
为什么你还不懂得怎么使用Python协程
May 13 Python
Python Django框架实现应用添加logging日志操作示例
May 17 Python
Falsk 与 Django 过滤器的使用与区别详解
Jun 04 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
Jul 22 Python
python实现对图片进行旋转,放缩,裁剪的功能
Aug 07 Python
使用python批量修改XML文件中图像的depth值
Jul 22 Python
谈谈python垃圾回收机制
Sep 27 Python
python计算列表元素与乘积详情
Aug 05 Python
利用Python+OpenCV三步去除水印
python实现自定义日志的具体方法
May 28 #Python
python 爬取京东指定商品评论并进行情感分析
python b站视频下载的五种版本
May 27 #Python
教你怎么用python selenium实现自动化测试
Python Django框架介绍之模板标签及模板的继承
May 27 #Python
python 算法题——快乐数的多种解法
May 27 #Python
You might like
PHP调用MySQL的存储过程的实现代码
2008/08/12 PHP
php对csv文件的读取,写入,输出下载操作详解
2013/08/10 PHP
PHP字符串word末字符实现大小写互换的方法
2014/11/10 PHP
自制PHP框架之设计模式
2017/05/07 PHP
7个有用的jQuery代码片段分享
2015/05/19 Javascript
JavaScript实现点击按钮就复制当前网址
2015/12/14 Javascript
JavaScript中各种引用类型的常用操作方法小结
2016/05/05 Javascript
微信小程序 Record API详解及实例代码
2016/09/30 Javascript
原生JS实现N级菜单的代码
2017/05/21 Javascript
JS实现的加减乘除四则运算计算器示例
2017/08/09 Javascript
js获取html页面代码中图片地址的实现代码
2018/03/05 Javascript
Node.js实现注册邮箱激活功能的方法示例
2018/03/23 Javascript
angularJs利用$scope处理升降序的方法
2018/10/08 Javascript
vue获取时间戳转换为日期格式代码实例
2019/04/17 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
微信小程序学习总结(三)条件、模板、文件引用实例分析
2020/06/04 Javascript
[03:59]第二届DOTA2亚洲邀请赛选手传记-VGJ.rOtk
2017/04/03 DOTA
Python发送以整个文件夹的内容为附件的邮件的教程
2015/05/06 Python
Python实现连接postgresql数据库的方法分析
2017/12/27 Python
详解Anconda环境下载python包的教程(图形界面+命令行+pycharm安装)
2019/11/11 Python
python处理RSTP视频流过程解析
2020/01/11 Python
python 函数中的参数类型
2020/02/11 Python
python中adb有什么功能
2020/06/07 Python
Pytorch 高效使用GPU的操作
2020/06/27 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
2020/12/10 Python
详解移动端Html5页面中1px边框的几种解决方法
2018/07/24 HTML / CSS
人事部岗位职责范本
2014/03/05 职场文书
给校长的建议书500字
2014/05/15 职场文书
求职信模板
2014/05/23 职场文书
企业法人代表证明书
2014/09/27 职场文书
婚内房产协议书范本
2014/10/02 职场文书
校园新闻广播稿5篇
2014/10/10 职场文书
2014年团委工作总结
2014/11/13 职场文书
大学生求职自荐信
2015/03/24 职场文书
详解Redis在SpringBoot工程中的综合应用
2021/10/16 Redis