python里的decimal类型转换

https://blog.csdn.net/kebu12345678/article/details/54845908

 

[Python标准库]decimal——定点数和浮点数的数学运算
        作用:使用定点数和浮点数的小数运算。
        Python 版本:2.4 及以后版本
        decimal 模块实现了定点和浮点算术运算符,使用的是大多数人所熟悉的模型,而不是程序员熟悉的模型,即大多数计算机硬件实现的 IEEE 浮点数运算。Decimal 实例可以准确地表示任何数,对其上取整或下取整,还可以对有效数字个数加以限制。
Decimal
        小数值表示为 Decimal 类的实例。构造函数取一个整数或字符串作为参数。使用浮点数创建 Decimal 之前,可以先将浮点数转换为一个字符串,使调用者能够显式地处理值得位数,倘若使用硬件浮点数表示则无法准确地表述。另外,利用类方法 from_float() 可以转换为精确的小数表示。

[python] view plain copy

  

  1. import decimal  
  2.   
  3. fmt = '{0:<25} {1:<25}'  
  4. print fmt.format('Input', 'Output')  
  5. print fmt.format('-' * 25, '-' * 25)  
  6.   
  7. # Integer  
  8. print fmt.format(5, decimal.Decimal(5))  
  9.   
  10. # String  
  11. print fmt.format('3.14', decimal.Decimal('3.14'))  
  12.   
  13. # Float  
  14. f = 0.1  
  15. print fmt.format(repr(f), decimal.Decimal(str(f)))  
  16. print fmt.format('%.23g' % f, str(decimal.Decimal.from_float(f))[:25])  

        浮点数值 0.1 并不表示为一个精确的二进制值,所以 float 的表示与 Decimal 值不同。在这个输出中它被截断为 25 个字符。
        Decimal 还可以由元组创建,其中包含一个符号标志(0 表示正,1 表示负)、数字 tuple 以及一个整数指数。

[python] view plain copy

  

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

        基于元组的表示创建时不太方便,不过它提供了一种可移植的方式,可以导出小数值而不会损失精度。tuple 形式可以在网络上传输,或者在不支持精确小数值得数据库中存储,以后再转回回 Decimal 实例。
算术运算
        Decimal 重载了简单的算术运算符,所以可以采用内置数值类型同样的方式处理 Decimal 实例。

[python] view plain copy

  

  1. import decimal  
  2.   
  3. a = decimal.Decimal('5.1')  
  4. b = decimal.Decimal('3.14')  
  5. c = 4  
  6. d = 3.14  
  7.   
  8. print 'a     =', repr(a)  
  9. print 'b     =', repr(b)  
  10. print 'c     =', repr(c)  
  11. print 'd     =', repr(d)  
  12. print  
  13.   
  14. print 'a + b =', a + b  
  15. print 'a - b =', a - b  
  16. print 'a * b =', a * b  
  17. print 'a / b =', a / b  
  18. print  
  19.   
  20. print 'a + c =', a + c  
  21. print 'a - c =', a - c  
  22. print 'a * c =', a * c  
  23. print 'a / c =', a / c  
  24. print  
  25.   
  26. print 'a + d =',  
  27. try:  
  28.     print a + d  
  29. except TypeError, e:  
  30.     print e  

        Decimal 运算符还接受整数参数,不过浮点数值必须转换为 Decimal 实例。
        除了基本算术运算,Decimal 还包括一些方法来查找以 10 为底的对数和自然对数。log10() 和 ln() 返回的值都是 Decimal 实例,所以可以与其他值一样直接在公式中使用。
特殊值
        除了期望的数字值,Decimal 还可以表示很多特殊值,包括正负无穷大值、“不是一个数”(NaN)和 0。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2.   
  3. for value in [ 'Infinity', 'NaN', '0' ]:  
  4.     print decimal.Decimal(value), decimal.Decimal('-' + value)  
  5. print  
  6.   
  7. # Math with infinity  
  8. print 'Infinity + 1:', (decimal.Decimal('Infinity') + 1)  
  9. print '-Infinity + 1:', (decimal.Decimal('-Infinity') + 1)  
  10.   
  11. # Print comparing NaN  
  12. print decimal.Decimal('NaN') == decimal.Decimal('Infinity')  
  13. print decimal.Decimal('NaN') != decimal.Decimal(1)  

        与无穷大值相加会返回另一个无穷大值。与 NaN 比较相等性总会返回 false,而比较不等性总会返回 true。与 NaN 比较大小来确定排序顺序没有明确定义,这会导致一个错误。
上下文
        到目前为止,前面的例子使用的都是 decimal 模块的默认行为。还可以使用一个上下文(context)覆盖某些设置,如保持精度、如何完成取整、错误处理等等。上下文可以应用于一个线程中的所有 Decimal 实例,或者局部应用于一个小代码区。
        1. 当前上下文
        要获取当前全局上下文,可以使用 getcontext()。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2. import pprint  
  3.   
  4. context = decimal.getcontext()  
  5.   
  6. print 'Emax     =', context.Emax  
  7. print 'Emin     =', context.Emin  
  8. print 'capitals =', context.capitals  
  9. print 'prec     =', context.prec  
  10. print 'rounding =', context.rounding  
  11. print 'flags    ='  
  12. pprint.pprint(context.flags)  
  13. print 'traps    ='  
  14. pprint.pprint(context.traps)  

        这个示例脚本显示了 Context 的公共属性。
        2. 精度
        上下文的 prec 属性控制着作为算术运算结果所创建的新值的精度。字面量值会按这个属性保持精度。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2.   
  3. d = decimal.Decimal('0.123456')  
  4. for i in range(4):  
  5.     decimal.getcontext().prec = i  
  6.     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 取整。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2.   
  3. context = decimal.getcontext()  
  4.   
  5. ROUNDING_MODES = [  
  6.     'ROUND_CEILING',  
  7.     'ROUND_DOWN',  
  8.     'ROUND_FLOOR',  
  9.     'ROUND_HALF_DOWN',  
  10.     'ROUND_HALF_EVEN',  
  11.     'ROUND_HALF_UP',  
  12.     'ROUND_UP',  
  13.     'ROUND_05UP',  
  14.     ]  
  15. header_fmt = '{:10} ' + ' '.join(['{:^8}'] * 6)  
  16. print header_fmt.format(' ',  
  17.                         '1/8 (1)', '-1/8 (1)',  
  18.                         '1/8 (2)', '-1/8 (2)',  
  19.                         '1/8 (3)', '-1/8 (3)',  
  20.                         )  
  21. for rounding_mode in ROUNDING_MODES:  
  22.     print '{0:10}'.format(rounding_mode.partition('_')[-1]),  
  23.     for precision in [ 1, 2, 3 ]:  
  24.         context.prec = precision  
  25.         context.rounding = getattr(decimal, rounding_mode)  
  26.         value = decimal.Decimal(1) / decimal.Decimal(8)  
  27.         print '{0:^8}'.format(value),  
  28.         value = decimal.Decimal(-1) / decimal.Decimal(8)  
  29.         print '{0:^8}'.format(value),  
  30.     print  

        这个程序显示了使用不同算法将同一个值取整为不同精度的效果。
        4. 局部上下文
        使用 Python 2.5 或以后版本时,可以使用 with 语句对一个代码块应用上下文。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2.   
  3. with decimal.localcontext() as c:  
  4.     c.prec = 2  
  5.     print 'Local precision:', c.prec  
  6.     print '3.14 / 3 =', (decimal.Decimal('3.14') / 3)  
  7. print  
  8. print 'Default precision:', decimal.getcontext().prec  
  9. print '3.14 / 3 =', (decimal.Decimal('3.14') / 3)  

        Context 支持 with 使用的上下文管理器 API,所以这个设置只在块内应用。
        5. 各实例上下文
        上下文还可以用来构造 Decimal 实例,然后可以从这个上下文继承精度和转换的取整参数。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2.   
  3. # Set up a context with limited precision  
  4. c = decimal.getcontext().copy()  
  5. c.prec = 3  
  6.   
  7. # Create our constant  
  8. pi = c.create_decimal('3.1415')  
  9.   
  10. # The constant value is rounded off  
  11. print 'PI    :', pi  
  12.   
  13. # The result of using the constant uses the global context  
  14. print 'RESULT:', decimal.Decimal('2.01') * pi  

        这样一来,应用就可以区别于用户数据精度而另外选择常量值精度。
        6. 线程
        “全局”上下文实际上是线程本地上下文,所以完全可以使用不同的值分别配置各个线程。

[python] view plain copy

  在CODE上查看代码片派生到我的代码片

  1. import decimal  
  2. import threading  
  3. from Queue import PriorityQueue  
  4.   
  5. class Multiplier(threading.Thread):  
  6.     def __init__(self, a, b, prec, q):  
  7.         self.a = a  
  8.         self.b = b  
  9.         self.prec = prec  
  10.         self.q = q  
  11.         threading.Thread.__init__(self)  
  12.     def run(self):  
  13.         c = decimal.getcontext().copy()  
  14.         c.prec = self.prec  
  15.         decimal.setcontext(c)  
  16.         self.q.put( (self.prec, a * b) )  
  17.         return  
  18.   
  19. a = decimal.Decimal('3.14')  
  20. b = decimal.Decimal('1.234')  
  21. # A PriorityQueue will return values sorted by precision, no matter  
  22. # what order the threads finish.  
  23. q = PriorityQueue()  
  24. threads = [ Multiplier(a, b, i, q) for i in range(1, 6) ]  
  25. for t in threads:  
  26.     t.start()  
  27.   
  28. for t in threads:  
  29.     t.join()  
  30.   
  31. for i in range(5):  
  32.     prec, value = q.get()  
  33.     print prec, '\t', value  

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您好!要将 Python 中的 Decimal 类型转换float 类型,可以使用 float() 函数。下面是一个示例代码: ```python from decimal import Decimal # 创建一个 Decimal 对象 x = Decimal('3.14') # 将 Decimal 转换float y = float(x) print(y) # 输出 3.14 print(type(y)) # 输出 <class 'float'> ``` 需要注意的是,将 Decimal 类型转换float 类型可能会导致精度丢失,因为 float 类型只能表示一定范围内的数字,无法表示所有的有理数。因此,建议在进行数值计算时使用 Decimal 类型,以避免精度丢失。 ### 回答2: Python中的decimal(小数)类型和float(浮点数)类型是不同的。在Python中,decimal类型可以进行高精度运算,避免了浮点数运算中的精度损失问题。但是在某些场景下,我们需要将decimal类型的数据转换float类型。 下面介绍两种方法将decimal类型转换float类型。 1.使用float()方法 我们可以使用Python内置的float()方法将decimal类型转换float类型。示例如下: ``` from decimal import Decimal x = Decimal('12.345') y = float(x) print('Decimal x:', x) print('Float y:', y) ``` 运行以上代码,输出结果如下: ``` Decimal x: 12.345 Float y: 12.345 ``` 2.使用quantize()方法 另一种方法是使用quantize()方法,该方法会将decimal类型的数据四舍五入到给定的精度,并将结果转换float类型。示例如下: ``` from decimal import Decimal, ROUND_HALF_UP x = Decimal('12.345') y = x.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) z = float(y) print('Decimal x:', x) print('Decimal y:', y) print('Float z:', z) ``` 运行以上代码,输出结果如下: ``` Decimal x: 12.345 Decimal y: 12.35 Float z: 12.35 ``` 其中,ROUND_HALF_UP参数表示四舍五入方式为“向最近的偶数舍入”(银行家舍入法),这是最常用的四舍五入方式。 需要注意的是,由于float类型的精度有限,可能会发生精度损失的情况,所以在转换时需要谨慎处理。 ### 回答3: Pythondecimalfloat 是两种不同的数据类型。Decimal 通常用于对精确计算的需要,而 float 用于对速度和内存使用的要求比较高的场合。如果需要将 decimal 转换float,则需要使用 float() 函数。 float 函数可以将一个数字或一个字符串转换float 类型。当使用 float() 函数将 decimal 转换float 时,需要注意的是保留的精度会降低,所以可能会存在精度丢失的问题。例如,如果一个 decimal 类型的数值为 0.1,转换float 后可能会成为 0.1000000001 或者其他类似的数值。 示例如下: ```python from decimal import Decimal d = Decimal('0.1') print(d) # 输出 0.1 f = float(d) print(f) # 输出 0.1(存在精度问题) ``` 在上面的示例中,首先定义了一个 Decimal 类型的数值,并将其赋值为字符串 '0.1' 。然后通过 float() 函数将其转换float 类型,并将结果赋值给变量 f 。由于精度的问题,最终输出的结果可能存在误差。 总之,在需要进行高精度计算的场合,应该使用 Decimal 类型进行计算,并在需要将结果输出或者传递给其他系统之前,需要考虑是否需要将其转换float 或者其他类型。如果需要将其转换float,则需要注意精度的问题,避免精度丢失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值