decimal模块

Python十进制数学计算模块decimal
Python提供了decimal模块用于十进制数学计算,它具有以下特点:

提供十进制数据类型,并且存储为十进制数序列;
有界精度:用于存储数字的位数是固定的,可以通过decimal.getcontext().prec=x 来设定,不同的数字可以有不同的精度
浮点:十进制小数点的位置不固定(但位数是固定的)
decimal的构建:

可以通过整数、字符串或者元组构建decimal.Decimal,对于浮点数需要先将其转换为字符串

decimal的context:

decimal在一个独立的context下工作,可以通过getcontext来获取当前环境。例如前面提到的可以通过decimal.getcontext().prec来设定小数点精度(默认为28):

>>> from decimal import Decimal as D
>>> from decimal import getcontext
>>> getcontext()
Context(prec=6, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[Rounded, Inexact], traps=[DivisionByZero, InvalidOperation, Overflow])
>>> getcontext().prec = 6
>>> D(1)/D(3)
Decimal(‘0.333333‘)
decimal和float性能对比:

python -mtimeit -s ‘from decimal import Decimal as D‘ ‘D("1.2")+D("3.4")‘
python -mtimeit -s ‘from decimal import Decimal as D‘ ‘1.2+3.4‘
我在虚拟机中测试前者耗时是后者的1.7k倍,但这在某些运算(例如财务运算)中是值得的,但如果要对非整数做上百次的运算,应坚持使用float。

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值)。

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了。

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操作;

原文地址:https://www.cnblogs.com/caodneg7/p/9683708.html

时间: 2024-10-01 16:06:33

decimal模块的相关文章

1.2 decimal模块

1 >>> 0.1 + 0.1 +0.1 == 0.3 2 False 3 >>> 4 >>> print(0.1 + 0.1 + 0.1) 5 0.30000000000000004 what??? 0.1 + 0.1 +0.1 == 0.3 判断为假 0.1 + 0.1 + 0.1 == 0.30000000000000004 可见Python中的浮点数的存储是不精确的.为毛捏? 因为内置的二进制浮点数实现 float是不精确的,这是二进制的问题.

用decimal模块增加python的浮点数精度

浮点数python默认是17位精度,也就是小数点后16位(16位以后的全部四舍五入了),虽然有16位,但是这个精度越往后越不准. 如果有特殊需求,需要更多的精度,可以用decimal模块,通过更改其里面getcontext()函数里面的prec参数,来决定你想要的浮点数精度. from decimal import Decimal from decimal import getcontext work_context = getcontext() work_context.prec = 100

decimal模块 --数字的精度、保留小数位数、取整问题

开始之前需要注意一点是:精度值为数字的总位数,如:1.23, 精度值为3: 0.123,精度值也为3 1.更改默认精度值后,直接进行计算即可保留对应范围值 from decimal import getcontext,Decimal getcontext().prec = 3 #设置精度值为3 f = 12.23435521 #type(f) : float value = Decimal(str(f)) #value: Decimal('12.23435521') #或:value = Dec

python decimal和fractions模块

1.简介 默认,浮点数学缺乏精确性 decimal 模块提供了一个 Decimal 数据类型用于浮点数计算.相比内置的二进制浮点数实现 float这个类型有助于金融应用和其它需要精确十进制表达的场合,控制精度,控制舍入以适应法律或者规定要求,确保十进制数位精度,或者用户希望计算结果与手算相符的场合.Decimal 重现了手工的数学运算,这就确保了二进制浮点数无法精确保有的数据精度. 高精度使 Decimal 可以执行二进制浮点数无法进行的模运算和等值测试. 2.使用 >>> from d

Python3 学习第十弹: 模块学习三之数字处理

math模块 提供基础的数学函数, cos(3.14) = -0.999..(弧度制) acos(1) = 0.0 sqrt(9) = 3.0 degrees(3.14) = 179.9999..(弧度转角度) radians(180) = 3.1415926..(角度转弧度) 常量 pi = 3.1415.. e = 2.7182.. cmath模块(complex math, 复数) 支持复数的运算, >>>import cmath >>>cmath.sqrt(-1

python的标准模块

本文用于记录python中的标准模块,随时更新. decimal模块(解决小数循环问题): >>> import decimal >>> a = decimal.Decimal('10.0') >>> b = decimal.Decimal('3') >>> a / b Decimal('3.333333333333333333333333333') fractions模块(解决分数表示问题): >>> from f

数字相关模块

整数可以利用bit_ length函 数测试所占的位数a =1;a.bit_ length()#a = 1024;a.bit length() # 11repr和str:显示格式的区别repr格式:默认的交互模式回显,产生的结果看起来它们就像是代码.str格式:打印语句,转化成一种对用户更加友好的格式.""" 数字相关的模块# math模块# Decimal模块:小数模块import decimalfrom decimal import DecimalDecimal(&quo

float精度丢失问题解决,用decimal.Decimal

首先来看一个浮点数运算:下面,当2个float类型数据,进行运算,就不能保证精度 a = 0.1b = 0.3print(a)print(b)print(b-a) 那么,怎么让上面的减法值,得到我们想要的 0.2 呢?导入 decimal模块,如果要不丢失精度Decimal类中必须要接收的是 str类型,如果还是传入 float类型,那么精度还是会丢失 import decimala = 0.1b = 0.3print(decimal.Decimal(str(b)) - decimal.Deci

decimal常用操作和需要注意的地方

decimal模块 简介 decimal意思为十进制,这个模块提供了十进制浮点运算支持. 常用方法 1.可以传递给Decimal整型或者字符串参数,但不能是浮点数据,因为浮点数据本身就不准确. 2.要从浮点数据转换为Decimal类型 from decimal import * Decimal.from_float(12.222) # 结果为Decimal('12.2219999999999995310417943983338773250579833984375') 3.通过设定有效数字,限定结