python语言中浮点数_在Python中截断浮点数
首先,函数,对于那些只想复制和粘贴代码的人:def truncate(f, n):
'''Truncates/pads a float f to n decimal places without rounding'''
s = '{}'.format(f)
if 'e' in s or 'E' in s:
return '{0:.{1}f}'.format(f, n)
i, p, d = s.partition('.')
return '.'.join([i, (d+'0'*n)[:n]])
这在Python2.7和3.1+中有效。对于较旧的版本,不可能获得相同的“智能舍入”效果(至少,不是没有很多复杂的代码),但是在截断之前舍入到12个小数位将在大部分时间内起作用:def truncate(f, n):
'''Truncates/pads a float f to n decimal places without rounding'''
s = '%.12f' % f
i, p, d = s.partition('.')
return '.'.join([i, (d+'0'*n)[:n]])
解释
底层方法的核心是以全精度将值转换为字符串,然后切掉超出所需字符数的所有内容。后面的步骤很简单;可以通过字符串操作来完成i, p, d = s.partition('.')
'.'.join([i, (d+'0'*n)[:n]])
或者decimal模块str(Decimal(s).quantize(Decimal((0, (1,), -n)), rounding=ROUND_DOWN))
第一步,转换成一个字符串,是相当困难的,因为有一些浮点文字对(即你在源代码中写的东西),它们都产生相同的二进制表示,但应该以不同的方式截断。例如,考虑0.3和0.299999999999998。如果您在Python程序中编写0.3,编译器会使用IEEE浮点格式将其编码为位序列(假设是64位浮点)0011111111010011001100110011001100110011001100110011001100110011
这是最接近0.3的值,可以精确地表示为IEEE浮点。但是,如果您在Python程序中编写0.29999999999999998,编译器会将其转换为与完全相同的值。在一种情况下,您的意思是它被截断为0.3,而在另一种情况下,您的意思是它被截断为0.2,但是Python只能给出一个答案。这是Python的一个基本限制,或者说是任何没有延迟计算的编程语言。截断函数只能访问存储在计算机内存中的二进制值,而不能访问您在源代码中实际键入的字符串。1
如果再次使用IEEE 64位浮点格式将位序列解码为十进制数,则0.2999999999999999888977697537484345957637...
所以一个天真的实现会产生0.2,尽管这可能不是你想要的。有关浮点表示错误的详细信息,see the Python tutorial。
使用非常接近一个整数但故意不等于该整数的浮点值是非常罕见的。因此,在截断时,从所有可能与内存中的值相对应的十进制表示中选择“最好的”十进制表示可能是有意义的。Python2.7及更高版本(但不是3.0)包含一个sophisticated algorithm to do just that,我们可以通过默认的字符串格式化操作访问它。'{}'.format(f)
唯一需要注意的是,这就像一个g格式规范,即如果数字足够大或足够小,它使用指数符号(1.23e+4)。所以这个方法必须抓住这个问题,并以不同的方式处理它。有一些情况下,使用f格式规范反而会导致问题,例如试图将3e-10截断为28位精度(它产生0.0000000002999999999999999980),我还不确定如何最好地处理这些问题。
如果实际上使用非常接近整数但故意不等于整数的floats(例如0.29999999999999998或99.95999999999994),这将产生一些误报,即它将舍入您不希望舍入的数字。在这种情况下,解决方案是指定固定精度。'{0:.{1}f}'.format(f, sys.float_info.dig + n + 2)
这里使用的精度位数并不重要,它只需要足够大,以确保在字符串转换中执行的任何舍入不会将值“提升”为其漂亮的十进制表示。我认为sys.float_info.dig + n + 2在所有情况下都是足够的,但如果不是这样的话2可能就必须增加,这样做并不有害。
在早期版本的Python(高达2.6或3.0)中,浮点数格式要粗糙得多,通常会产生如下内容>>> 1.1
1.1000000000000001
如果这是你的情况,如果你想使用“nice”十进制对于截断的表示,您所能做的(据我所知)就是选择一些位数,小于可以用float表示的全精度,并在截断之前将该位数舍入到该位数。一个典型的选择是12'%.12f' % f
但是你可以调整这个以适应你正在使用的数字。
1好吧。。。我撒谎了。技术上,您可以指示Python重新解析它自己的源代码,并提取与传递给truncation函数的第一个参数对应的部分。如果该参数是浮点文字,则只需将其截断小数点后的某个位置,然后返回。但是,如果参数是变量,则此策略不起作用,这使得它相当无用。以下仅为娱乐价值:def trunc_introspect(f, n):
'''Truncates/pads the float f to n decimal places by looking at the caller's source code'''
current_frame = None
caller_frame = None
s = inspect.stack()
try:
current_frame = s[0]
caller_frame = s[1]
gen = tokenize.tokenize(io.BytesIO(caller_frame[4][caller_frame[5]].encode('utf-8')).readline)
for token_type, token_string, _, _, _ in gen:
if token_type == tokenize.NAME and token_string == current_frame[3]:
next(gen) # left parenthesis
token_type, token_string, _, _, _ = next(gen) # float literal
if token_type == tokenize.NUMBER:
try:
cut_point = token_string.index('.') + n + 1
except ValueError: # no decimal in string
return token_string + '.' + '0' * n
else:
if len(token_string) < cut_point:
token_string += '0' * (cut_point - len(token_string))
return token_string[:cut_point]
else:
raise ValueError('Unable to find floating-point literal (this probably means you called {} with a variable)'.format(current_frame[3]))
break
finally:
del s, current_frame, caller_frame
将其泛化以处理传入变量的情况似乎是一个失败的原因,因为在找到赋予变量值的浮点文字之前,必须向后跟踪程序的执行过程。如果真的有。大多数变量将从用户输入或数学表达式初始化,在这种情况下,二进制表示就是全部。
python语言中浮点数_在Python中截断浮点数相关推荐
- 以下关于python语言技术特点_关于Python语言的特点,以下选项中描述错误的是
关于Python语言的特点,以下选项中描述错误的是 答:Python语言是非开源语言 为<素问>补充了"天元纪大论"等7篇大论的医家是: 答:王冰 中国大学MOOC: ...
- 哪些不符合python语言变量名_以下选项中不符合 Python 语言变量命名规则的是( )_学小易找答案...
[单选题]下列各项中,关于银行存款业务的表述中正确的是( ).(2012年) [单选题]下列各项中,关于企业无法查明原因的现金溢余,经批准后应贷记的会计科目是( ). [多选题]计价软件中,在人材机汇 ...
- 动漫的python语言代码大全_使用Python来看看动漫中的你
百度人工智能运用世界领先的对抗生成网络,结合人脸检测.头发分割.人像分割等技术,为用户量身定制千人千面的二次元动漫形象,并且可通过参数设置,生成戴口罩的二次元动漫人像. 先来一组图看看效果 八种口罩任 ...
- python语言运算符有三种_《Python语言程序设计》 —2.3 运算符
2.3 运算符 在计算机中,数据处理实际上就是对数据按照一定的规则进行运算.在已经掌握Python基本数据类型的基础上,我们来看一下对这些类型的数据可以做哪些运算.这里介绍数据处理中一些常用运算符的作 ...
- python语言程序设计项目_《Python语言程序设计》项目报告书Word版
<<Python语言程序设计>项目报告书Word版>由会员分享,可在线阅读,更多相关<<Python语言程序设计>项目报告书Word版(8页珍藏版)>请 ...
- python语言好不好_《python编程基础》这本书怎么样
<python编程基础>这本书怎么样 发布时间:2020-11-11 12:01:06 来源:亿速云 阅读:73 作者:小新 小编给大家分享一下<python编程基础>这本书怎 ...
- python语言面试基础_【python面试指北】1.语言基础
1. python是动态强类型的语言. 动态还是静态指的是编译器还是运行期确定类型 强类型指的是不会发生隐式类型转换.比如js能够执行1+"1",但是python不行,所以pyth ...
- 用python语言自我介绍_使用Python实现自我介绍
从此课程开始,学习中使用的Python IDE(集成开发环境)都是PyCharm,大家可以根据自己的喜好来选择自己喜欢的Python IDE. 打印自我介绍 打开PyCharm,在test.py文件中 ...
- 九九乘法表python语言编程软件_编写Python程序,输出如下的九九乘法表_学小易找答案...
[其它]写出下图的梯形图程序对应的语句表 (26.0分) [简答题]PLC一般的编程语言有几种?分别是什么? (5.0分) [其它]定义一个getMax函数,返回三个数(从键盘输入的整数)中的最大值. ...
- python语言要多久_自学Python一般需要多久
自学Python一般需要多久 发布时间:2020-11-12 10:41:41 来源:亿速云 阅读:67 作者:小新 这篇文章主要介绍了自学Python一般需要多久,具有一定借鉴价值,需要的朋友可以参 ...
最新文章
- nginx + gunicorn + django的简单部署
- python基础语法手册format-python基础_格式化输出(%用法和format用法)
- android 检测当前wifi是否又网络,android判断连接的wifi是否能访问网络
- iOS学习之iOS沙盒(sandbox)机制和文件操作(二)
- Word保存自己格式模板的方法
- 和卷积的区别_[CVPR2019]:最新高效卷积方式HetConv
- c++ 标准库中 cin.ignore()
- 使用ABAP操作Excel的几种方法
- java用中点画圆法_OpenGL通过中点法绘制直线和圆
- --.net 面试题2
- MySQL索引常用算法
- SyntaxError: Missing parentheses in call to 'print' 这个错误原因是Python版本问题
- google 翻译 api
- MIUI目前为止最简单安装谷歌服务框架教程
- 微信公众号 开发详解05【二维码制作、调查表单、短网址、微小宝、引流】
- 海康威视NVR硬盘录像机DS-7808N安装调试教程,监控系统安装教程
- Google镜像网站全(4-3更)
- C语言实现可伸缩的栈结构
- Vue安装element ui踩坑
- 三分钟集成 TapTap 登录 SDK(Unity 版)