python中的decimal类型转换实例详解


Posted in Python onJune 26, 2019

[Python标准库]decimal——定点数和浮点数的数学运算

        作用:使用定点数和浮点数的小数运算。
        Python 版本:2.4 及以后版本

        decimal 模块实现了定点和浮点算术运算符,使用的是大多数人所熟悉的模型,而不是程序员熟悉的模型,即大多数计算机硬件实现的 IEEE 浮点数运算。Decimal 实例可以准确地表示任何数,对其上取整或下取整,还可以对有效数字个数加以限制。

Decimal

         小数值表示为 Decimal 类的实例。构造函数取一个整数或字符串作为参数。使用浮点数创建 Decimal 之前,可以先将浮点数转换为一个字符串,使调用者能够显式地处理值得位数,倘若使用硬件浮点数表示则无法准确地表述。另外,利用类方法 from_float() 可以转换为精确的小数表示。 

import decimal 
fmt = '{0:<25} {1:<25}' 
print fmt.format('Input', 'Output') 
print fmt.format('-' * 25, '-' * 25) 
# Integer 
print fmt.format(5, decimal.Decimal(5)) 
# String 
print fmt.format('3.14', decimal.Decimal('3.14')) 
# Float 
f = 0.1 
print fmt.format(repr(f), decimal.Decimal(str(f))) 
print fmt.format('%.23g' % f, str(decimal.Decimal.from_float(f))[:25])

        浮点数值 0.1 并不表示为一个精确的二进制值,所以 float 的表示与 Decimal 值不同。在这个输出中它被截断为 25 个字符。

        Decimal 还可以由元组创建,其中包含一个符号标志(0 表示正,1 表示负)、数字 tuple 以及一个整数指数。 

import decimal 
# Tuple 
t = (1, (1, 1), -2) 
print 'Input :', t 
print 'Decimal:', decimal.Decimal(t)

        基于元组的表示创建时不太方便,不过它提供了一种可移植的方式,可以导出小数值而不会损失精度。tuple 形式可以在网络上传输,或者在不支持精确小数值得数据库中存储,以后再转回回 Decimal 实例。

算术运算

        Decimal 重载了简单的算术运算符,所以可以采用内置数值类型同样的方式处理 Decimal 实例。

import decimal 
a = decimal.Decimal('5.1') 
b = decimal.Decimal('3.14') 
c = 4 
d = 3.14 
print 'a  =', repr(a) 
print 'b  =', repr(b) 
print 'c  =', repr(c) 
print 'd  =', repr(d) 
print 
print 'a + b =', a + b 
print 'a - b =', a - b 
print 'a * b =', a * b 
print 'a / b =', a / b 
print 
print 'a + c =', a + c 
print 'a - c =', a - c 
print 'a * c =', a * c 
print 'a / c =', a / c 
print 
print 'a + d =', 
try: 
 print a + d 
except TypeError, e: 
 print e

        Decimal 运算符还接受整数参数,不过浮点数值必须转换为 Decimal 实例。

        除了基本算术运算,Decimal 还包括一些方法来查找以 10 为底的对数和自然对数。log10() 和 ln() 返回的值都是 Decimal 实例,所以可以与其他值一样直接在公式中使用。

特殊值  

      除了期望的数字值,Decimal 还可以表示很多特殊值,包括正负无穷大值、“不是一个数”(NaN)和 0。

import decimal 
for value in [ 'Infinity', 'NaN', '0' ]: 
 print decimal.Decimal(value), decimal.Decimal('-' + value) 
print 
# Math with infinity 
print 'Infinity + 1:', (decimal.Decimal('Infinity') + 1) 
print '-Infinity + 1:', (decimal.Decimal('-Infinity') + 1) 
# Print comparing NaN 
print decimal.Decimal('NaN') == decimal.Decimal('Infinity') 
print decimal.Decimal('NaN') != decimal.Decimal(1)

        与无穷大值相加会返回另一个无穷大值。与 NaN 比较相等性总会返回 false,而比较不等性总会返回 true。与 NaN 比较大小来确定排序顺序没有明确定义,这会导致一个错误。

上下文

        到目前为止,前面的例子使用的都是 decimal 模块的默认行为。还可以使用一个上下文(context)覆盖某些设置,如保持精度、如何完成取整、错误处理等等。上下文可以应用于一个线程中的所有 Decimal 实例,或者局部应用于一个小代码区。     

 1. 当前上下文

        要获取当前全局上下文,可以使用 getcontext()。

import decimal 
import pprint 
context = decimal.getcontext() 
print 'Emax   =', context.Emax 
print 'Emin   =', context.Emin 
print 'capitals =', context.capitals 
print 'prec   =', context.prec 
print 'rounding =', context.rounding 
print 'flags  =' 
pprint.pprint(context.flags) 
print 'traps  =' 
pprint.pprint(context.traps)

        这个示例脚本显示了 Context 的公共属性。

        2. 精度

        上下文的 prec 属性控制着作为算术运算结果所创建的新值的精度。字面量值会按这个属性保持精度。

import decimal 
d = decimal.Decimal('0.123456') 
for i in range(4): 
  decimal.getcontext().prec = i 
  print i, ':', d, d * 1

        要改变精度,可以直接为这个属性赋一个新值。

        3. 取整

        取整有多种选择,以保证值在所需精度范围内。

•ROUND_CEILING 总是趋向于无穷大向上取整。
•ROUND_DOWN 总是趋向 0 取整。
•ROUND_FLOOR 总是趋向负无穷大向下取整。
•ROUND_HALF_DOWN 如果最后一个有效数字大于或等于 5 则朝 0 反方向取整;否则,趋向 0 取整。
•ROUND_HALF_EVEN 类似于 ROUND_HALF_DOWN,不过,如果最后一个有效数字值为 5,则会检查前一位。偶数值会导致结果向下取整,奇数值导致结果向上取整。
•ROUND_HALF_UP 类似于 ROUND_HALF_DOWN,不过如果最后一位有效数字为 5,值会朝 0 的反方向取整。
•ROUND_UP 朝 0 的反方向取整。
•ROUND_05UP 如果最后一位是 0 或 5,则朝 0 的反方向取整;否则向 0 取整。

import decimal 
 context = decimal.getcontext() 
ROUNDING_MODES = [ 
  'ROUND_CEILING', 
  'ROUND_DOWN', 
  'ROUND_FLOOR', 
  'ROUND_HALF_DOWN', 
  'ROUND_HALF_EVEN', 
  'ROUND_HALF_UP', 
  'ROUND_UP', 
  'ROUND_05UP', 
  ] 
header_fmt = '{:10} ' + ' '.join(['{:^8}'] * 6) 
print header_fmt.format(' ', 
            '1/8 (1)', '-1/8 (1)', 
            '1/8 (2)', '-1/8 (2)', 
            '1/8 (3)', '-1/8 (3)', 
            ) 
for rounding_mode in ROUNDING_MODES: 
  print '{0:10}'.format(rounding_mode.partition('_')[-1]), 
  for precision in [ 1, 2, 3 ]: 
    context.prec = precision 
    context.rounding = getattr(decimal, rounding_mode) 
    value = decimal.Decimal(1) / decimal.Decimal(8) 
    print '{0:^8}'.format(value), 
    value = decimal.Decimal(-1) / decimal.Decimal(8) 
    print '{0:^8}'.format(value), 
  print

 这个程序显示了使用不同算法将同一个值取整为不同精度的效果。

        4. 局部上下文

        使用 Python 2.5 或以后版本时,可以使用 with 语句对一个代码块应用上下文。

import decimal 
with decimal.localcontext() as c: 
  c.prec = 2 
  print 'Local precision:', c.prec 
  print '3.14 / 3 =', (decimal.Decimal('3.14') / 3) 
print 
print 'Default precision:', decimal.getcontext().prec 
print '3.14 / 3 =', (decimal.Decimal('3.14') / 3)

      Context 支持 with 使用的上下文管理器 API,所以这个设置只在块内应用。

        5. 各实例上下文

        上下文还可以用来构造 Decimal 实例,然后可以从这个上下文继承精度和转换的取整参数。

import decimal 
# Set up a context with limited precision 
c = decimal.getcontext().copy() 
c.prec = 3 
# Create our constant 
pi = c.create_decimal('3.1415') 
# The constant value is rounded off 
print 'PI  :', pi 
 
# The result of using the constant uses the global context 
print 'RESULT:', decimal.Decimal('2.01') * pi

        这样一来,应用就可以区别于用户数据精度而另外选择常量值精度。

        6. 线程

        “全局”上下文实际上是线程本地上下文,所以完全可以使用不同的值分别配置各个线程。

import decimal 
import threading 
from Queue import PriorityQueue 
class Multiplier(threading.Thread): 
  def __init__(self, a, b, prec, q): 
    self.a = a 
    self.b = b 
    self.prec = prec 
    self.q = q 
    threading.Thread.__init__(self) 
  def run(self): 
    c = decimal.getcontext().copy() 
    c.prec = self.prec 
 decimal.setcontext(c) 
    self.q.put( (self.prec, a * b) ) 
    return 
 a = decimal.Decimal('3.14') 
b = decimal.Decimal('1.234') 
# A PriorityQueue will return values sorted by precision, no matter 
# what order the threads finish. 
q = PriorityQueue() 
threads = [ Multiplier(a, b, i, q) for i in range(1, 6) ] 
for t in threads: 
  t.start() 
 
for t in threads: 
  t.join() 
 
for i in range(5): 
  prec, value = q.get() 
  print prec, '\t', value

这个例子使用指定的值创建一个新的上下文,然后安装到各个线程中。

总结

以上所述是小编给大家介绍的python中的decimal类型转换实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python笔记(2)
Oct 24 Python
跟老齐学Python之通过Python连接数据库
Oct 28 Python
Python实现获取命令行输出结果的方法
Jun 10 Python
python判断字符串是否是json格式方法分享
Nov 07 Python
Python随机生成均匀分布在单位圆内的点代码示例
Nov 13 Python
python中requests和https使用简单示例
Jan 18 Python
Python实现的序列化和反序列化二叉树算法示例
Mar 02 Python
Python解析json代码实例解析
Nov 25 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
Mar 06 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
如何用Python徒手写线性回归
Jan 25 Python
Pyside2中嵌入Matplotlib的绘图的实现
Feb 22 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
Jun 26 #Python
ipython和python区别详解
Jun 26 #Python
使用Python计算玩彩票赢钱概率
Jun 26 #Python
java中的控制结构(if,循环)详解
Jun 26 #Python
PyQt5实现QLineEdit添加clicked信号的方法
Jun 25 #Python
pyqt5 键盘监听按下enter 就登陆的实例
Jun 25 #Python
PyQt5响应回车事件的方法
Jun 25 #Python
You might like
PHP 只允许指定IP访问(允许*号通配符过滤IP)
2014/07/08 PHP
php操作redis缓存方法分享
2015/06/03 PHP
使用PHP进行微信公众平台开发的示例
2015/08/21 PHP
php pdo操作数据库示例
2017/03/10 PHP
基于php编程规范(详解)
2017/08/17 PHP
javascript动画效果类封装代码
2007/08/28 Javascript
jQuery)扩展jQuery系列之一 模拟alert,confirm(一)
2010/12/04 Javascript
js限制文本框只能输入数字(正则表达式)
2012/07/15 Javascript
JSON+JavaScript处理JSON的简单例子
2013/03/20 Javascript
JavaScript实现点击单选按钮改变输入框中文本域内容的方法
2015/08/12 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
浅谈bootstrap源码分析之scrollspy(滚动侦听)
2016/06/06 Javascript
全面解析JavaScript中apply和call以及bind(推荐)
2016/06/15 Javascript
快速解决js动态改变dom元素属性后页面及时渲染的问题
2016/07/06 Javascript
jQuery简单实现彩色云标签效果示例
2016/08/01 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
vue-cli初始化项目中使用less的方法
2018/08/09 Javascript
通过实践编写优雅的JavaScript代码
2019/05/30 Javascript
vue表单中遍历表单操作按钮的显示隐藏示例
2019/10/30 Javascript
Vue 防止短时间内连续点击后多次触发请求的操作
2020/11/11 Javascript
全面了解Python环境配置及项目建立
2016/06/30 Python
使用tensorflow实现AlexNet
2017/11/20 Python
python正则表达式爬取猫眼电影top100
2018/02/24 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
python读取各种文件数据方法解析
2018/12/29 Python
Python实现线性判别分析(LDA)的MATLAB方式
2019/12/09 Python
python实现跨excel sheet复制代码实例
2020/03/03 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
举例讲解Python装饰器
2020/12/24 Python
欧缇丽英国官方网站:Caudalie英国
2016/08/17 全球购物
太阳镜仓库,售价20美元或更少:Sunglass Warehouse
2016/09/28 全球购物
考试作弊被抓检讨书
2014/01/10 职场文书
小学教师办公室制度
2014/02/03 职场文书
优秀经理获奖感言
2014/03/04 职场文书
大型活动组织方案
2014/05/10 职场文书
公司应聘自荐书
2014/06/14 职场文书