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

[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类型转换实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • python类型强制转换long to int的代码

    python2.4版本以后,如果int的值超出范围不会溢出,而是内部转换为long,在网上没有找到从long型强制转换成int的代码,这里所说的int取值范围是和java里一致,即用四个字节表示.自己写了一个函数,勉强可以用,供大家参考. 复制代码 代码如下: import sysdef LongToInt(value):    assert isinstance(value, (int, long))    return int(value & sys.maxint) 经过测试,在32位和64

  • Python中实现字符串类型与字典类型相互转换的方法

    本文以实例形式简述了Python中字符串类型与字典类型相互转换的方法,是比较实用的功能.具体方法如下: 一.字典(dict)转为字符串(string) 我们可以比较容易的将字典(dict)类型转为字符串(string)类型. 通过遍历dict中的所有元素就可以实现字典到字符串的转换: for key, value in sample_dic.items(): print "\"%s\":\"%s\"" % (key, value) 二.字符串(s

  • python编程开发之类型转换convert实例分析

    本文实例讲述了python编程开发之类型转换convert.分享给大家供大家参考,具体如下: 在python的开发过程中,难免会遇到类型转换,这里给出常见的类型转换demo: int(x [,base ])         将x转换为一个整数    long(x [,base ])        将x转换为一个长整数    float(x )               将x转换到一个浮点数    complex(real [,imag ])  创建一个复数    str(x )        

  • 常用python数据类型转换函数总结

    1.chr(i)chr()函数返回ASCII码对应的字符串. 复制代码 代码如下: >>> print chr(65)A>>> print chr(66) >>> print chr(65)+chr(66)AB 2.complex(real[,imaginary])complex()函数可把字符串或数字转换为复数. 复制代码 代码如下: >>> complex("2+1j")(2+1j)>>> c

  • 浅谈Python数据类型之间的转换

    Python数据类型之间的转换 函数 描述 int(x [,base]) 将x转换为一个整数 long(x [,base] ) 将x转换为一个长整数 float(x) 将x转换到一个浮点数 complex(real [,imag]) 创建一个复数 str(x) 将对象 x 转换为字符串 repr(x) 将对象 x 转换为表达式字符串 eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象 tuple(s) 将序列 s 转换为一个元组 list(s) 将序列 s 转换为一个

  • 在Python中处理字符串之isdecimal()方法的使用

    isdecimal()方法检查字符串是否仅由十进制字符组成.此方法只存在于unicode对象. 注意:要定义一个字符串为Unicode,只需前缀分配'u'左引号.以下是示例. 语法 以下是isdecimal()方法的语法: str.isdecimal() 参数 NA 返回值 如果字符串中的所有字符为十进制此方法返回true,否则返回false. 例子 下面的例子显示了isdecimal()方法的使用. #!/usr/bin/python str = u"this2009"; print

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

    [Python标准库]decimal--定点数和浮点数的数学运算 作用:使用定点数和浮点数的小数运算.         Python 版本:2.4 及以后版本 decimal 模块实现了定点和浮点算术运算符,使用的是大多数人所熟悉的模型,而不是程序员熟悉的模型,即大多数计算机硬件实现的 IEEE 浮点数运算.Decimal 实例可以准确地表示任何数,对其上取整或下取整,还可以对有效数字个数加以限制. Decimal 小数值表示为 Decimal 类的实例.构造函数取一个整数或字符串作为参数.使用

  • Python 中迭代器与生成器实例详解

    Python 中迭代器与生成器实例详解 本文通过针对不同应用场景及其解决方案的方式,总结了Python中迭代器与生成器的一些相关知识,具体如下: 1.手动遍历迭代器 应用场景:想遍历一个可迭代对象中的所有元素,但是不想用for循环 解决方案:使用next()函数,并捕获StopIteration异常 def manual_iter(): with open('/etc/passwd') as f: try: while True: line=next(f) if line is None: br

  • Python中的Django基本命令实例详解

    一.新建项目 $django-admin.py  startproject  project_name # 特别是在 windows 上,如果报错,尝试用 django-admin 代替 django-admin.py 试试 注意 project_name 是自己的项目名称,需要为合法的 Python 包名,如不能为 1a 或 a-b. 二.新建APP 要先进入项目目录下,cd project_name 然后执行下面的命令: $ python manage.py startapp app_nam

  • Python中logging日志库实例详解

    logging的简单使用 用作记录日志,默认分为六种日志级别(括号为级别对应的数值) NOTSET(0) DEBUG(10) INFO(20) WARNING(30) ERROR(40) CRITICAL(50) special 在自定义日志级别时注意不要和默认的日志级别数值相同 logging 执行时输出大于等于设置的日志级别的日志信息,如设置日志级别是 INFO,则 INFO.WARNING.ERROR.CRITICAL 级别的日志都会输出. |2logging常见对象 Logger:日志,

  • python中的unittest框架实例详解

    在python中我们学习了不少理论知识,那么对相关的程序进行测试,就显得很重要了.本篇要讲的是unittest框架,我们可以用它来做一些测试工作,又或者是相关代码的编写.下面我们就unittest框架的说明.特性和4种字模块分别带来介绍,大家一起来看具体内容. 1.unittest说明 unittest是Python自带的单元测试框,具备编写用例.组织用例.执行用例.输出报告等自动化框架的条件,可以用来作自动化测试框架的用例组织执行框架. 2.unittest框架特性 (1)提供用例组织与执行:

  • Python中optparser库用法实例详解

    本文研究的主要是Python中optparser库的相关内容,具体如下. 一直以来对optparser不是特别的理解,今天就狠下心,静下心研究了一下这个库.当然了,不敢说理解的很到位,但是足以应付正常的使用了.废话不多说,开始今天的分享吧. 简介 optparse模块主要用来为脚本传递命令参数功能. 引入 在IDE中引入optparser是很方便的. from optparser import OptionParser 初始化 相对而言,初始化需要我们多注意一点点了. 因为我们有两种不同的方式来

  • python中urllib模块用法实例详解

    本文实例讲述了python中urllib模块用法.分享给大家供大家参考.具体分析如下: 一.问题: 近期公司项目的需求是根据客户提供的api,我们定时去获取数据, 之前的方案是用php收集任务存入到redis队列,然后在linux下做一个常驻进程跑某一个php文件, 该php文件就一个无限循环,判断redis队列,有就执行,没有就break. 二.解决方法: 最近刚好学了一下python, python的urllib模块或许比php的curl更快,而且简单. 贴一下代码 复制代码 代码如下: #

  • python中字典(Dictionary)用法实例详解

    本文实例讲述了python中字典(Dictionary)用法.分享给大家供大家参考.具体分析如下: 字典(Dictionary)是一种映射结构的数据类型,由无序的"键-值对"组成.字典的键必须是不可改变的类型,如:字符串,数字,tuple:值可以为任何python数据类型. 1.新建字典 >>> dict1={} #建立一个空字典 >>> type(dict1) <type 'dict'> 2.增加字典元素:两种方法 >>&g

  • Python中subprocess模块用法实例详解

    本文实例讲述了Python中subprocess模块用法.分享给大家供大家参考.具体如下: 执行命令: >>> subprocess.call(["ls", "-l"]) 0 >>> subprocess.call("exit 1", shell=True) 1 测试调用系统中cmd命令,显示命令执行的结果: x=subprocess.check_output(["echo", "

  • python中argparse模块用法实例详解

    本文实例讲述了python中argparse模块用法.分享给大家供大家参考.具体分析如下: 平常在写命令行工具的时候,经常会带参数,所以用python中的argparse来实现. # -*- coding: utf-8 -*- import argparse args = "-f hello.txt -n 1 2 3 -x 100 -y b -z a -q hello @args.txt i_am_bar -h".split() # 使用@args.txt要求fromfile_pref

随机推荐