首先,函数,对于那些只想复制和粘贴代码的人: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中截断浮点数相关推荐

  1. 以下关于python语言技术特点_关于Python语言的特点,以下选项中描述错误的是

    关于Python语言的特点,以下选项中描述错误的是 答:Python语言是非开源语言 为<素问>补充了"天元纪大论"等7篇大论的医家是: 答:王冰 中国大学MOOC: ...

  2. 哪些不符合python语言变量名_以下选项中不符合 Python 语言变量命名规则的是( )_学小易找答案...

    [单选题]下列各项中,关于银行存款业务的表述中正确的是( ).(2012年) [单选题]下列各项中,关于企业无法查明原因的现金溢余,经批准后应贷记的会计科目是( ). [多选题]计价软件中,在人材机汇 ...

  3. 动漫的python语言代码大全_使用Python来看看动漫中的你

    百度人工智能运用世界领先的对抗生成网络,结合人脸检测.头发分割.人像分割等技术,为用户量身定制千人千面的二次元动漫形象,并且可通过参数设置,生成戴口罩的二次元动漫人像. 先来一组图看看效果 八种口罩任 ...

  4. python语言运算符有三种_《Python语言程序设计》 —2.3 运算符

    2.3 运算符 在计算机中,数据处理实际上就是对数据按照一定的规则进行运算.在已经掌握Python基本数据类型的基础上,我们来看一下对这些类型的数据可以做哪些运算.这里介绍数据处理中一些常用运算符的作 ...

  5. python语言程序设计项目_《Python语言程序设计》项目报告书Word版

    <<Python语言程序设计>项目报告书Word版>由会员分享,可在线阅读,更多相关<<Python语言程序设计>项目报告书Word版(8页珍藏版)>请 ...

  6. python语言好不好_《python编程基础》这本书怎么样

    <python编程基础>这本书怎么样 发布时间:2020-11-11 12:01:06 来源:亿速云 阅读:73 作者:小新 小编给大家分享一下<python编程基础>这本书怎 ...

  7. python语言面试基础_【python面试指北】1.语言基础

    1. python是动态强类型的语言. 动态还是静态指的是编译器还是运行期确定类型 强类型指的是不会发生隐式类型转换.比如js能够执行1+"1",但是python不行,所以pyth ...

  8. 用python语言自我介绍_使用Python实现自我介绍

    从此课程开始,学习中使用的Python IDE(集成开发环境)都是PyCharm,大家可以根据自己的喜好来选择自己喜欢的Python IDE. 打印自我介绍 打开PyCharm,在test.py文件中 ...

  9. 九九乘法表python语言编程软件_编写Python程序,输出如下的九九乘法表_学小易找答案...

    [其它]写出下图的梯形图程序对应的语句表 (26.0分) [简答题]PLC一般的编程语言有几种?分别是什么? (5.0分) [其它]定义一个getMax函数,返回三个数(从键盘输入的整数)中的最大值. ...

  10. python语言要多久_自学Python一般需要多久

    自学Python一般需要多久 发布时间:2020-11-12 10:41:41 来源:亿速云 阅读:67 作者:小新 这篇文章主要介绍了自学Python一般需要多久,具有一定借鉴价值,需要的朋友可以参 ...

最新文章

  1. nginx + gunicorn + django的简单部署
  2. python基础语法手册format-python基础_格式化输出(%用法和format用法)
  3. android 检测当前wifi是否又网络,android判断连接的wifi是否能访问网络
  4. iOS学习之iOS沙盒(sandbox)机制和文件操作(二)
  5. Word保存自己格式模板的方法
  6. 和卷积的区别_[CVPR2019]:最新高效卷积方式HetConv
  7. c++ 标准库中 cin.ignore()
  8. 使用ABAP操作Excel的几种方法
  9. java用中点画圆法_OpenGL通过中点法绘制直线和圆
  10. --.net 面试题2
  11. MySQL索引常用算法
  12. SyntaxError: Missing parentheses in call to 'print' 这个错误原因是Python版本问题
  13. google 翻译 api
  14. MIUI目前为止最简单安装谷歌服务框架教程
  15. 微信公众号 开发详解05【二维码制作、调查表单、短网址、微小宝、引流】
  16. 海康威视NVR硬盘录像机DS-7808N安装调试教程,监控系统安装教程
  17. Google镜像网站全(4-3更)
  18. C语言实现可伸缩的栈结构
  19. Vue安装element ui踩坑
  20. 三分钟集成 TapTap 登录 SDK(Unity 版)

热门文章

  1. JS精粹知识点和我的解释
  2. 2.2.4 ES 6语法与ES 5语法
  3. mysql -prompt选项
  4. 内存交换空间(swap)
  5. Unity 之圆环算法
  6. MySQL中exists和in的区别
  7. Java中的线程池回顾总结
  8. scrollView截取指定区域的图片
  9. 从零开始用Python3做数据分析
  10. WPF 控件 深度克隆