原文:https://blog.csdn.net/lemonwyc/article/details/37583125

上一节提到了除了基本类型之外的decimal,这节就学习下。

查看python3.4.1文档,发现对于decimal模块的讲解非常多,由此可见其功能也很强大(下面算是把我认为比较重要的半翻译半学习吧~)。文档关于decimal模块的总解释是Decimal fixed point and floating point arithmetic,我理解的是固定小数点和浮点运算。头加上from decimal import * 即可调用decimal模块中的内容。

1. Decimal类型的优点

Decimal类型是在浮点类型的基础上设计的,但是它在几个地方上要优于floating point:

1)Decimal类型可以非常精确地在计算机中存储,而学过c++的都知道,浮点型在计算机中是无法精确存储的,比如1.1和2.2在计算机中存储后,运算(1.1+2.2)表达式的值结果会是3.3000000000000003;Decimal类型则不会出现这种情况。同样,由于无法精确存储,浮点型也就无法精确计算(相对于Decimal类型),可以再测试(0.1+0.1+0.1-0.3)两种类型的计算结果。

2)Decimal类型会自动保留小数点后面不需要的0,以与输入的精度相匹配,比如下面小程序中的例子:浮点型的1.20+1.30结果是2.5;而Decimal类型结果是2.50,这样貌似比较人性化。

3)Decimal类型可以根据需要自己设置小数点后精度。通过getcontext().prec = x (x为你想要的精度来设置,getcontext()函数下面再详细介绍)。

4)Decimal类型有很强的管理功能,它能够根据需要设置,来控制输出的格式,得到或者忽略某类错误(如除0,可以设置忽略它,而得到一个Infinity的Decimal值)。

#difference between float and decimal

print(1.1+2.2) #3.3000000000000003

print (Decimal('1.1')+Decimal('2.2')) #3.3

print (0.1+0.1+0.1-0.3) #5.551115123125783e-17

print (Decimal('0.1')+Decimal('0.1')+Decimal('0.1')-Decimal('0.3')) # 0.0

print (1.20+1.30) #2.5

print (Decimal('1.20')+Decimal('1.30')) #2.50

需要注意的是,Decimal()的构造中如果是小数或字符的话,需要加上单引号;如果为整数,则不需要。

2. decimal模块的构成

文档说,decimal模块主要由三部分构成:the decimal number ,the context of arithmetic ,signals 。

1)decimal number是不可改变的常量,它也不会截取小数点后多余的0;除了正常的数外, 它还包括'Infinity','-Infinity','NaN'等数。

2)the context of arithmetic是当前计算环境的一些参数,包括精度位数prec,舍弃位数规则rounding,指数的最大值最小值Emin、Emax,科学计数法e的大小写Capitals,指数是否超出范围clamped,运算结果的标志flags,哪些操作要触发traps等。

3)signals是在运算过程中产生的一些状态,这些状态可以根据需要用来提示、忽略、报错等。

signals和flags、traps是对应的,假设运算过程中产生了除0这样一个状态,那么flags中就会产生一个DivisionByZero为1这样的信息,接着如果在traps中包含这个操作,那么python就会报个异常出来。这样一个处理机制,可以人为的设置自己需要的信息或异常提示,而把另外一些忽略。

3. context

可以用getcontext()函数得到当前运算环境的参数,直接打印 print (get context()),以我的为例子

Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, Overflow, DivisionByZero])

其中,prec精度为28,是默认值,可以通过getcontext().prec = 10这样来设置自己想要的精度;rounding的规则是ROUND_HALF_EVEN (具体下面介绍),此外还有其他一些规则,感兴趣的可以查阅文档或自己测试;traps数组表明当前如果出现这三种状态会报异常。当然,其中的参数都可以自己修改。

值得一提的是,精度值的修改只在运算中才会体现出来,比如精度是5,输入Decimal(’1.222222222‘),输出仍然是这个数;但是Decimal('1.222222222') + Decimal('1.11111111') 的结果精度就为6了。

除了可以通过getcontext().prec这样来修改context的参数,还可以使用setcontext()来一次性设置context。如下:

mycontext = Context(prec=18, rounding=ROUND_HALF_DOWN)

setcontext(mycontext)

这里再学习一个比较有用的函数quantize(),当我们希望在运算过程中保持较高的精度,而在结果中以某种方式保留几位小数时可以用这个函数,下面是官网文档的示例:

Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)

Decimal('7.32') #result

Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)

Decimal('8') #result

4. Signals

decimal模块中提供了10种signals,下面简单介绍一下:

1)Clamped:越界,指数超出Emin或Emax范围;如果发生,则会在小数部分添加0来表示;

2)DecimalException;

3)DivisionByZero:在除法运算中出现,除数为0;如果不捕捉该错误,则返回Infinity或-Infinity;

4)Inexact:不精确,使用round函数舍弃的小数部分中包含除0以外的数字;

5)InvalidOperation:无效计算或计算无意义,比如两个无穷大相减等;如果不捕捉该错误,则返回NaN(Not a Number);

6)Overflow:在round后指数超出Emax范围,如果不捕捉,则根据round规则来判断返回什么值;

7)Rounded:如果round操作舍弃了小数,不管是不是0,都发生;如果不捕捉,则返回 值未改变;

8)Subnormal:指数值过小;如果不捕捉,则返回  值不变;

9)Underflow:指数值太小,且round操作向0逼近;

10)FloatOperation:如果不捕捉,则混合float型和Decimal型的操作可以执行;如果捕捉,则只有相等判断和显式转换可以执行,其余的都报错。

5. Round类型

Decimal中大致有以下几种类型,做简单介绍一下,如有错误,希望指正:

1)ROUND_UP:舍弃小数部分非0时,在前面增加数字,如 5.21 -> 5.3;

2)ROUND_DOWN:舍弃小数部分,从不在前面数字做增加操作,如5.21->5.2;

3)ROUND_CEILING:如果Decimal为正,则做ROUND_UP操作;如果Decimal为负,则做ROUND_DOWN操作;

4)ROUND_FLOOR:如果Decimal为负,则做ROUND_UP操作;如果Decimal为正,则做ROUND_DOWN操作;

5)ROUND_HALF_DOWN:如果舍弃部分>.5,则做ROUND_UP操作;否则,做ROUND_DOWN操作;

6)ROUND_HALF_UP:如果舍弃部分>=.5,则做ROUND_UP操作;否则,做ROUND_DOWN操作;

7)ROUND_HALF_EVEN:如果舍弃部分左边的数字是奇数,则做ROUND_HALF_UP操作;若为偶数,则做ROUND_HALF_DOWN操作;

#test Round rules

#ROUND_UP & ROUND_DOWN

print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_UP)) #8.54

print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_UP)) #-8.54

print (Decimal('8.530').quantize(Decimal('0.01'), rounding=ROUND_UP)) #8.53

print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_DOWN)) #8.53

print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_DOWN)) #8.53

#ROUND_CEILING & ROUND_FLOOR

print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_CEILING)) #8.54

print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_CEILING))#-8.53

print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_FLOOR)) #8.53

print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_FLOOR)) #-8.54

#ROUND_HALF_

print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) #8.54

print (Decimal('8.534').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) #8.53

print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.53

print (Decimal('8.534').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.53

print (Decimal('8.536').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.54

print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN)) #8.54

print (Decimal('8.545').quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN)) #8.54

decimal模块先简单了解到这里,还有许多函数,后面如果用到,再查阅文档。

python decimal函数_(转)python学习笔记5--decimal相关推荐

  1. python搞笑语句_云计算开发学习笔记:Python3 import语句

    原标题:云计算开发学习笔记:Python3 import语句 想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下: 当解释器遇到 import 语句,如果模块在当前的 ...

  2. python 魔法函数 __add___PythonI/O进阶学习笔记_2.魔法函数

    前言: 本文一切观点和测试代码是在python3的基础上. Content: 1.什么是魔法函数,魔法函数__getitem__在python中应用. 2.python的数据模型和数据模型这种设计对p ...

  3. python自定义函数复制字符串_Python学习笔记摘要(一)类型 字符串 函数 列表 深浅拷贝...

    python中的对象和类型 在python中,认为系统中的每一个"东西"都是一个对象,在python中,"对象"有着特殊的意义,python中的对象有: 一个标 ...

  4. python pos函数_使用python+sklearn实现特征提取

    sklearn.feature_extraction模块可用于以机器学习算法支持的格式从原始数据集(如文本和图像)中提取特征.**注意:**特征提取与特征选择有很大不同:前者是将任意数据(例如文本或图 ...

  5. python isalnum函数_探究Python中isalnum()方法的使用

    探究Python中isalnum()方法的使用 isalnum()方法检查判断字符串是否包含字母数字字符. 语法 以下是isalnum()方法的语法: str.isa1num() 参数 NA 返回值 ...

  6. python deepcopy函数_用Python解数独[6]:递归获得最终答案

    目录 用Python解数独[0] 用Python解数独[1]:求每个单元格的行值域 用Python解数独[2]:求列值域和九宫格值域 用Python解数独[3]:求总值域 用Python解数独[4]: ...

  7. python 微积分 函数_用Python学微积分(2)---复合函数

    函数的复合(Composition) 定义:设函数y=f(u)和u=g(x)u=g(x),则函数y=f[g(x)]称为由y=f(u)和u=g(x)复合而成的复合函数,其中函数y=f(u)常常称为外函数 ...

  8. python商业爬虫_商业爬虫学习笔记day1

    day1 一. HTTP 1.介绍: https://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html http://blog.csdn.ne ...

  9. python用函数绘制椭圆_Python学习笔记——opencv绘制椭圆

    在Python环境下使用opencv绘制椭圆,需要用到cv2.ellipse() 函数. 下面一段示例程序就是用该函数在黑色背景下,绘制一个圆心在(260,240).长轴170.短轴130.线宽为3的 ...

最新文章

  1. Web service到底是什么?
  2. 分类算法之朴素贝叶斯分类(Naive Bayesian classification)
  3. python3.7 6如何安装-centos安装python3.7
  4. python表白源代码-python七夕浪漫表白源码
  5. 如何在Mac下显示Finder中的所有文件
  6. 教你用 Netty 实现一个简单的 RPC!
  7. 自动化测试框架搭建-参数化-3
  8. windows 通过批处理 修改环境变量
  9. eclipse实现Android登录功能,eclipse开发安卓登录
  10. caffe新手常遇到的三个问题
  11. OSGI开发web应用
  12. func_ext.php,fsockopen和pfsockopen函数替换
  13. Linux下的IO监控与分析
  14. Inno SetUp中文语言包以及在脚本中使用
  15. 浪潮服务器管理口地址linux系统,浪潮服务器管理口BMC通用设置
  16. 直接学 Vue 3 吧 —— 对话 Vue.js 作者尤雨溪
  17. 程序员专属手机壁纸来了。。。
  18. 数据库之Oracle笔试面试题收集(来自网络)
  19. 聚观早报 | 嘀嗒出行重启赴港IPO;饿了么到店业务将与高德合并
  20. SEO——搜索引擎优化

热门文章

  1. php 控制函数执行时间,php set_time_limit(0) 设置程序执行时间的函数
  2. 利用Java GUI,结合Java Socket,Java多线程,服务器,制作一个简单的具有界面的多用户实时聊天程序(从GUI,到Socket,到多线程,到服务器,项目级别详细教程)
  3. 说到比心源码,不如讲讲比心源码实现聊天室功能该怎么做?
  4. 普元nui:Lists列表
  5. AliyunIoTSDK升级,支持绑定自定义主题
  6. 网络安全攻防演练的组织架构是什么?有哪些防守手段?
  7. python 中的魔术方法 getitem setitem
  8. 实体关系 (ER) 图的几种不同风格的符号
  9. Mybase:DIY自己的知识数据库
  10. 我正在翻译的CakePHP manual