python decimal函数_python--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模块先简单了解到这里,还有许多函数,后面如果用到,再查阅文档。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Pythondecimal模块提供了高精度计算功能,它可以处理浮点数的精度问题,避免浮点数计算过程中出现精度丢失的问题。 下面是使用decimal模块的一些常见操作: 1. 创建Decimal对象: 可以使用字符串或数字创建Decimal对象,例如: ```python import decimal # 使用字符串创建Decimal对象 x = decimal.Decimal('0.1') print(x) # 使用数字创建Decimal对象 y = decimal.Decimal(0.1) print(y) ``` 2. 精度设置: 可以通过getcontext()方法获取当前的精度设置,并使用prec属性来设置精度,例如: ```python import decimal # 获取当前精度设置 context = decimal.getcontext() # 设置精度为4位 context.prec = 4 # 进行计算 x = decimal.Decimal('1') / decimal.Decimal('7') print(x) ``` 3. 四舍五入: 可以使用quantize()方法来实现四舍五入,例如: ```python import decimal x = decimal.Decimal('0.12345') y = x.quantize(decimal.Decimal('0.01'), rounding=decimal.ROUND_HALF_UP) print(y) ``` 在这个例子中,我们将x四舍五入到两位小数,并使用ROUND_HALF_UP模式进行四舍五入。 4. 精度运算: 使用Decimal对象进行数值计算时,会自动进行精度控制,例如: ```python import decimal x = decimal.Decimal('0.1') y = decimal.Decimal('0.2') z = x + y print(z) ``` 在这个例子中,由于0.1和0.2在浮点数中无法精确表示,因此使用Decimal对象进行计算时,会自动进行精度控制,避免出现精度丢失的问题。 以上就是一些常见的使用Decimal模块的操作方法。 ### 回答2: Pythondecimal模块提供了一个高精度的十进制运算器,它允许我们进行更精确的数字计算和定点计算。它的主要作用是保证精度,避免浮点数运算带来的误差,从而得到更准确的结果。这个模块提供了与float类型不同的精度,可以用于商业、金融及其他需要精度的计算。 decimal的使用步骤如下: 1.导入decimal模块: import decimal 2.设置精度位数:decimal.getcontext().prec = n 3.进行精确计算:使用decimal.Decimal()函数 下面是decimal的一些常用函数: 1. decimal.Decimal(str or value):将字符串或数字转换为Decimal对象 2. decimal.getcontext().prec = n:设置精度位数 3. object.quantize(demical.Decimal(rounding = ROUND_HALF_UP)):四舍五入,保留小数位数 4. object.to_eng_string():以字符串格式返回Decimal对象 使用例子: 1. 需要设置精度位数 ``` import decimal decimal.getcontext().prec = 4 result = decimal.Decimal(1) / decimal.Decimal(3) print(result) ``` 结果为: 0.3333 2. 进行精确计算 ``` import decimal x = decimal.Decimal('3.14159') y = decimal.Decimal('2.71828') result = x * y print(result) ``` 结果为: 8.53972952 3. 四舍五入,保留小数位数 ``` import decimal x = decimal.Decimal('3.14159') y = decimal.Decimal('2.71828') result = (x * y).quantize(decimal.Decimal('0.00')) print(result) ``` 结果为: 8.54 总的来说,使用decimal模块可以让我们进行更加精准的数字计算,避免浮点数运算带来的误差。当需要进行金融和商业计算时,decimal模块尤其有用。 ### 回答3: Pythondecimal函数是用来精确计算小数的一个库,可以实现高精度小数计算。在Python中,自带的float类型只能保留15到17位的有效数字,如果需要更高的精度,就需要使用decimaldecimal函数的基本用法如下: 1. 引入decimal库: 先使用import decimaldecimal库引入Python: ```python import decimal ``` 2. 创建decimal对象: 要使用Decimal创建一个十进制数,需要使用字符串或整数作为参数。例如: ```python a = decimal.Decimal('0.1') # 创建一个小数 b = decimal.Decimal(10) # 创建一个整数 ``` 3. 进行计算: 使用上述创建的对象,可以进行数学计算,例如: ```python print(a + b) print(a * b) print(a / b) ``` decimal支持的精度可由用户指定,也可以使用getcontext()函数来设置当前环境的全局精度。 ```python decimal.getcontext().prec = 30 # 将全局精度设置为30位 ``` 值得一提的是,Decimal对于小数的四则运算不同于float类型,会尽可能地保留精度。例如: ```python >>> 0.1 + 0.1 + 0.1 - 0.3 5.551115123125783e-17 ``` 这是因为float类型不能够精确地表示小数,而使用Decimal则可以解决这个问题: ```python >>> d = decimal.Decimal(0.1) >>> d + d + d - decimal.Decimal(0.3) Decimal('0.0') ``` 总之,Pythondecimal函数可以让程序员实现高精度小数计算,使得在科学计算、金融计算、数据分析等领域更加精确可靠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值