• decimal模块


    decimal模块支持快速正确舍入的十进制浮点运算。它提供了优于float数据类型的几个优点 :

    • Decimal“基于浮点模型,它是为人们设计的,并且必然具有最重要的指导原则 – 计算机必须提供与人们在学校学习的算法相同的算法。” – 摘录自十进制算术规范。

    • 十进制数字可以准确表示。相反,数字喜欢 1.12.2不具有二进制浮点的精确表示。最终用户通常不希望显示二进制浮点数。1.1 2.23.3000000000000003

    • 精确性延续到算术中。在十进制浮点数中,恰好等于零。在二进制浮点中,结果是。虽然接近于零,但差异阻止了可靠的相等性测试,并且差异可能会累积。因此,在具有严格相等不变量的会计应用程序中,decimal是首选。0.1 0.1 0.1 0.35.5511151231257827e-017

    • 小数模块具有显著场所的概念,这样是。保留尾随零以表示重要性。这是货币申请的惯常陈述。对于乘法,“教科书”方法使用被乘数中的所有数字。举例来说,给人的同时给人。1.30 1.202.501.3 *1.21.561.30 1.201.5600

    • 与基于硬件的二进制浮点不同,十进制模块具有用户可更改的精度(默认为28个位置),可以与给定问题所需的一样大:

      1. >>> from decimal import *
      2. >>> getcontext().prec = 6
      3. >>> Decimal(1) / Decimal(7)
      4. Decimal('0.142857')
      5. >>> getcontext().prec = 28
      6. >>> Decimal(1) / Decimal(7)
      7. Decimal('0.1428571428571428571428571429')
    • 二进制和十进制浮点都是根据已发布的标准实现的。虽然内置浮点类型只公开其功能的一小部分,但十进制模块公开了标准的所有必需部分。在需要时,程序员可以完全控制舍入和信号处理。这包括通过使用异常来阻止任何不精确操作来强制执行精确算术的选项。

    • 十进制模块旨在支持“无偏见,精确的非连续十进制算术(有时称为定点算术)和舍入浮点算术。” – 摘自十进制算术规范。

    模块设计以三个概念为中心:十进制数,算术上下文和信号。

    十进制数是不可变的。它有一个符号,系数数字和一个指数。为了保持重要性,系数数字不会截断尾随零。小数也包括特殊值,如 Infinity-InfinityNaN。该标准还区分-0+0

    算术的上下文是指定精度,舍入规则,指数限制,指示操作结果的标志以及确定信号是否被视为异常的陷阱启用器的环境。舍入选项包括ROUND_CEILINGROUND_DOWN, ROUND_FLOORROUND_HALF_DOWNROUND_HALF_EVENROUND_HALF_UPROUND_UP,和ROUND_05UP

    信号是在计算过程中出现的异常条件组。根据应用程序的需要,信号可能会被忽略,被视为信息,或被视为异常。十进制模块中的信号是:ClampedInvalidOperation, DivisionByZeroInexactRoundedSubnormalOverflowUnderflowFloatOperation

    对于每个信号,都有一个标志和一个陷阱使能器。遇到信号时,其标志设置为1,然后,如果陷阱启用器设置为1,则引发异常。标志是粘性的,因此用户需要在监控计算之前重置它们。

    也可以看看

    • IBM的通用十进制算术规范,通用十进制算术规范。

    快速入门教程

    通常使用小数的开始是导入模块,查看当前上下文,getcontext()并在必要时为精度,舍入或启用的陷阱设置新值:

    1. >>>
    2. >>> from decimal import *
    3. >>> getcontext()
    4. Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
    5. capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero,
    6. InvalidOperation])
    7. >>> getcontext().prec = 7 # Set a new precision

    可以从整数,字符串,浮点数或元组构造十进制实例。从整数或浮点构造将执行该整数或浮点值的精确转换。十进制数字包括特殊值,例如 NaN“非数字”,正数和负数 Infinity,以及-0

    1. >>>
    2. >>> getcontext().prec = 28
    3. >>> Decimal(10)
    4. Decimal('10')
    5. >>> Decimal('3.14')
    6. Decimal('3.14')
    7. >>> Decimal(3.14)
    8. Decimal('3.140000000000000124344978758017532527446746826171875')
    9. >>> Decimal((0, (3, 1, 4), -2))
    10. Decimal('3.14')
    11. >>> Decimal(str(2.0 ** 0.5))
    12. Decimal('1.4142135623730951')
    13. >>> Decimal(2) ** Decimal('0.5')
    14. Decimal('1.414213562373095048801688724')
    15. >>> Decimal('NaN')
    16. Decimal('NaN')
    17. >>> Decimal('-Infinity')
    18. Decimal('-Infinity')

    如果FloatOperation信号被捕获,构造函数中的小数和浮点数的意外混合或排序比较会引发异常:

    1. >>>
    2. >>> c = getcontext()
    3. >>> c.traps[FloatOperation] = True
    4. >>> Decimal(3.14)
    5. Traceback (most recent call last):
    6. File "<stdin>", line 1, in <module>
    7. decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
    8. >>> Decimal('3.5') < 3.7
    9. Traceback (most recent call last):
    10. File "<stdin>", line 1, in <module>
    11. decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
    12. >>> Decimal('3.5') == 3.5
    13. True

    版本3.3中的新功能。

    新十进制的重要性仅由输入的位数决定。上下文精度和舍入仅在算术运算期间发挥作用。

    1. >>> getcontext().prec = 6
    2. >>> Decimal('3.0')
    3. Decimal('3.0')
    4. >>> Decimal('3.1415926535')
    5. Decimal('3.1415926535')
    6. >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    7. Decimal('5.85987')
    8. >>> getcontext().rounding = ROUND_UP
    9. >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    10. Decimal('5.85988')

    如果超出C版本的内部限制,则构造十进制会引发InvalidOperation

    1. >>>
    2. >>> Decimal("1e9999999999999999999")
    3. Traceback (most recent call last):
    4. File "<stdin>", line 1, in <module>
    5. decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

    版本3.3已更改。

    小数与Python的其余部分很好地交互。这是一个小的十进制浮点飞行马戏团:

    1. >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
    2. >>> max(data)
    3. Decimal('9.25')
    4. >>> min(data)
    5. Decimal('0.03')
    6. >>> sorted(data)
    7. [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
    8. Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
    9. >>> sum(data)
    10. Decimal('19.29')
    11. >>> a,b,c = data[:3]
    12. >>> str(a)
    13. '1.34'
    14. >>> float(a)
    15. 1.34
    16. >>> round(a, 1)
    17. Decimal('1.3')
    18. >>> int(a)
    19. 1
    20. >>> a * 5
    21. Decimal('6.70')
    22. >>> a * b
    23. Decimal('2.5058')
    24. >>> c % a
    25. Decimal('0.77')

    Decimal也可以使用一些数学函数:

    1. >>> getcontext().prec = 28
    2. >>> Decimal(2).sqrt()
    3. Decimal('1.414213562373095048801688724')
    4. >>> Decimal(1).exp()
    5. Decimal('2.718281828459045235360287471')
    6. >>> Decimal('10').ln()
    7. Decimal('2.302585092994045684017991455')
    8. >>> Decimal('10').log10()
    9. Decimal('1')

    quantize()方法将数字四舍五入为固定指数。此方法对于通常将结果舍入到固定数量的位置的货币应用程序非常有用:

    
    
    1. >>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
    2. Decimal('7.32')
    3. >>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
    4. Decimal('8')

    如上所示,该getcontext()函数访问当前上下文并允许更改设置。这种方法满足大多数应用程序的需求。

    对于更高级的工作,使用Context()构造函数创建备用上下文可能很有用。要使备用激活,请使用该setcontext() 功能。

    按照标准,该decimal模块提供两种准备使用标准的上下文,BasicContextExtendedContext。前者对调试特别有用,因为许多陷阱都已启用:

    1. >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
    2. >>> setcontext(myothercontext)
    3. >>> Decimal(1) / Decimal(7)
    4. Decimal('0.142857142857142857142857142857142857142857142857142857142857')
    5. >>> ExtendedContext
    6. Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
    7. capitals=1, clamp=0, flags=[], traps=[])
    8. >>> setcontext(ExtendedContext)
    9. >>> Decimal(1) / Decimal(7)
    10. Decimal('0.142857143')
    11. >>> Decimal(42) / Decimal(0)
    12. Decimal('Infinity')
    13. >>> setcontext(BasicContext)
    14. >>> Decimal(42) / Decimal(0)
    15. Traceback (most recent call last):
    16. File "<pyshell#143>", line 1, in -toplevel-
    17. Decimal(42) / Decimal(0)
    18. DivisionByZero: x / 0

    上下文还具有用于监视计算期间遇到的异常情况的信号标志。标志保持设置直到明确清除,因此最好使用该clear_flags()方法清除每组受监控计算之前的标志。

    1. >>>
    2. >>> setcontext(ExtendedContext)
    3. >>> getcontext().clear_flags()
    4. >>> Decimal(355) / Decimal(113)
    5. Decimal('3.14159292')
    6. >>> getcontext()
    7. Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
    8. capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[])

    标志条目显示合理的近似Pi四舍五入(数字超出范围内精度被扔掉了),而且结果不准确(有些丢弃数字为非零)。

    使用traps上下文字段中的字典设置单个陷阱:

    1. >>> setcontext(ExtendedContext)
    2. >>> Decimal(1) / Decimal(0)
    3. Decimal('Infinity')
    4. >>> getcontext().traps[DivisionByZero] = 1
    5. >>> Decimal(1) / Decimal(0)
    6. Traceback (most recent call last):
    7. File "<pyshell#112>", line 1, in -toplevel-
    8. Decimal(1) / Decimal(0)
    9. DivisionByZero: x / 0

    大多数程序仅在程序开始时调整当前上下文一次。并且,在许多应用程序中,数据Decimal在循环内转换为单个强制转换。通过创建上下文集和小数,程序的大部分操作数据与其他Python数字类型没有区别。

    十进制对象

    class decimal.Decimalvalue =“0”context = None 
    Decimal根据构造一个新对象。

    value可以是整数,字符串,元组float或其他Decimal 对象。如果没有给出,则返回Decimal('0')。如果value是一个字符串,它应该在前导和尾随空白字符以及整个下划线被删除后符合十进制数字字符串语法:

    1. sign ::= '+' | '-'
    2. digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    3. indicator ::= 'e' | 'E'
    4. digits ::= digit [digit]...
    5. decimal-part ::= digits '.' [digits] | ['.'] digits
    6. exponent-part ::= indicator [sign] digits
    7. infinity ::= 'Infinity' | 'Inf'
    8. nan ::= 'NaN' [digits] | 'sNaN' [digits]
    9. numeric-value ::= decimal-part [exponent-part] | infinity
    10. numeric-string ::= [sign] numeric-value | [sign] nan

    digit 如上所示,也允许使用其他Unicode十进制数字。这些包括来自各种其他字母表十进制数字与全角数字的沿(例如,阿拉伯-印度文和梵文位数)'uff10'通过'uff19'

    如果value是a tuple,它应该有三个组件,一个符号(0对于正数或1负数),一个tuple数字和一个整数指数。例如, 退货。Decimal((0, (1, 4, 1, 4), -3))Decimal('1.414')

    如果value为a float,则将二进制浮点值无损地转换为其精确的十进制等效值。此转换通常需要53位或更多位数的精度。例如,Decimal(float('1.1')) 转换为Decimal('1.100000000000000088817841970012523233890533447265625')

    背景下的精度并不影响多少位被存储。这是由在数字位数专门确定。例如,Decimal('3.00000')即使上下文精度仅为3 ,也 记录所有五个零。

    context参数的目的是确定如果value是格式错误的字符串,该怎么做。如果上下文陷阱InvalidOperation,则会引发异常; 否则,构造函数返回一个值为的新Decimal NaN

    一旦构造,Decimal对象就是不可变的。

    在3.2版中更改:现在允许构造函数的参数成为float 实例。

    在版本3.3中更改:float如果FloatOperation 设置了陷阱,则参数会引发异常。默认情况下,陷阱已关闭。

    在版本3.6中更改:允许使用下划线进行分组,与代码中的整数和浮点文字一样。

    十进制浮点对象与其他内置数值类型(如float和)共享许多属性int。所有常用的数学运算和特殊方法都适用。同样,十进制对象可以被复制,腌制,打印,用作字典键,用作设置元素,比较,排序和强制转换为另一种类型(例如float或 int)。

    算术对十进制对象和算术对整数和浮点数有一些小的差别。当余数运算符%应用于Decimal对象时,结果的符号是 被除数的符号,而不是除数的符号:

    1. >>>
    2. >>> (-7) % 4
    3. 1
    4. >>> Decimal(-7) % Decimal(4)
    5. Decimal('-3')

    整数除法运算符的//行为类似,返回真商的整数部分(截断为零)而不是其底限,以便保留通常的标识:==(x // y) y

    1. >>>
    2. >>> -7 // 4
    3. -2
    4. >>> Decimal(-7) // Decimal(4)
    5. Decimal('-1')

    %//运营商实现remainder和 divide-integer操作(分别)如说明书中所述。

    十进制对象通常不能与浮点数或fractions.Fraction算术运算中的实例组合:例如,尝试将a添加Decimal到a float将引发a TypeError。但是,可以使用Python的比较运算符将Decimal 实例x与另一个数字进行比较y。这样可以避免在对不同类型的数字进行相等比较时混淆结果。

    版本3.2中已更改:Decimal现在完全支持实例与其他数字类型之间的混合类型比较。

    除了标准的数字属性,十进制浮点对象还有许多专门的方法:

    adjusted
    在移出系数最右边的数字后返回调整后的指数,直到只剩下前导数字: Decimal('321e+5').adjusted()返回7。用于确定最高有效位相对于小数点的位置。
    as_integer_ratio
    返回一对表示给定实例的整数 作为分数,以最低的值表示并带有正分母:(n, d)Decimal
    1. >>>
    2. >>> Decimal('-3.14').as_integer_ratio()
    3. (-157, 50)

    转换是准确的。在Infinities上引发OverflowError,在NaNs上引起ValueError。

    版本3.6中的新功能。

    as_tuple
    返回数字的命名元组表示: 。DecimalTuple(sign, digits, exponent)
    canonical
    返回参数的规范编码。目前,Decimal实例的编码始终是规范的,因此该操作返回其参数不变。
    compare其他context = None 
    比较两个Decimal实例的值。 compare()返回一个Decimal实例,如果任一操作数是NaN,那么结果是NaN:
    1. a or b is a NaN ==> Decimal('NaN')
    2. a < b ==> Decimal('-1')
    3. a == b ==> Decimal('0')
    4. a > b ==> Decimal('1')
    compare_signal其他context = None 
    compare()除了所有NaN信号之外,该操作与该方法相同。也就是说,如果两个操作数都不是信令NaN,那么任何安静的NaN操作数都被视为信令NaN。
    compare_total其他context = None 
    使用它们的抽象表示而不是它们的数值来比较两个操作数。与compare()方法类似,但结果给出了Decimal实例的总排序。Decimal具有相同数值但不同表示的两个 实例在此排序中比较不相等:
    1. >>> Decimal('12.0').compare_total(Decimal('12'))
    2. Decimal('-1')

    安静和信号NaN也包括在总排序中。此函数的结果是,Decimal('0')如果两个操作数具有相同的表示形式,Decimal('-1')如果第一个操作数的总顺序低于第二个Decimal('1')操作数,并且第一个操作数的总顺序高于第二个操作数。有关总订单的详细信息,请参阅规范。

    此操作不受上下文影响且安静:不更改任何标志且不执行舍入。作为例外,如果无法准确转换第二个操作数,则C版本可能会引发InvalidOperation

    compare_total_mag其他context = None 
    比较两个操作数使用它们的抽象表示而不是它们的值compare_total(),但忽略每个操作数的符号。x.compare_total_mag(y)相当于 x.copy_abs().compare_total(y.copy_abs())

    此操作不受上下文影响且安静:不更改任何标志且不执行舍入。作为例外,如果无法准确转换第二个操作数,则C版本可能会引发InvalidOperation。

    conjugate
    只返回self,这种方法只符合Decimal规范。
    copy_abs
    返回参数的绝对值。此操作不受上下文影响并且很安静:没有更改标志且不执行舍入。
    copy_negate
    回到论证的否定。此操作不受上下文影响并且很安静:没有更改标志且不执行舍入。
    copy_sign其他context = None 
    返回第一个操作数的副本,其符号设置为与第二个操作数的符号相同。例如:
    1. >>> Decimal('2.3').copy_sign(Decimal('-1.5'))
    2. Decimal('-2.3')

    此操作不受上下文影响且安静:不更改任何标志且不执行舍入。作为例外,如果无法准确转换第二个操作数,则C版本可能会引发InvalidOperation

    expcontext = None 
    返回e**x给定数字处的(自然)指数函数的值。使用ROUND_HALF_EVEN舍入模式正确舍入结果 。
    1. >>> Decimal(1).exp()
    2. Decimal('2.718281828459045235360287471')
    3. >>> Decimal(321).exp()
    4. Decimal('2.561702493119680037517373933E+139')
    from_float
    将float转换为十进制数的Classmethod。

    注意Decimal.from_float(0.1)Decimal(’0.1’)不同。由于0.1在二进制浮点中不能精确表示,因此该值存储为最接近的可表示值,即 0x1.999999999999ap-4。十进制的等效值为0.1000000000000000055511151231257827021181583404541015625

    注意

    从Python 3.2开始,Decimal实例也可以直接从a构造float

    1. >>> Decimal.from_float(0.1)
    2. Decimal('0.1000000000000000055511151231257827021181583404541015625')
    3. >>> Decimal.from_float(float('nan'))
    4. Decimal('NaN')
    5. >>> Decimal.from_float(float('inf'))
    6. Decimal('Infinity')
    7. >>> Decimal.from_float(float('-inf'))
    8. Decimal('-Infinity')

    3.1版中的新功能。

    fma其他第三上下文=无
    融合乘法加法。返回自我*其他+第三,没有中间产品自我*其他的四舍五入。
    1. >>> Decimal(2).fma(3, 5)
    2. Decimal('11')
    is_canonical
    True如果参数是规范的,False 则返回。目前,Decimal实例始终是规范的,因此此操作始终返回True
    is_finite
    返回True如果参数是一个有限数量,以及 False如果参数为无穷大或为NaN。
    is_infinite
    返回True如果参数为正或负无穷大,False否则。
    is_nan
    返回True如果参数是(安静或信令)的NaN和 False其它。
    is_normalcontext = None 
    True如果参数是正常的有限数,则返回。返回 False如果参数为0,低于正常,无穷大或NaN的。
    is_qnan
    True如果参数是一个安静的NaN,则返回, False否则返回。
    is_signed
    True如果参数有负号,False则返回, 否则返回。请注意,零和NaN都可以带有符号。
    is_snan
    True如果参数是信号NaN则返回,False 否则返回。
    is_subnormalcontext = None 
    True如果参数是次正规则返回,False 否则返回。
    is_zero
    True如果参数为(正或负)零,False则返回, 否则返回。
    lncontext = None 
    返回操作数的自然(基数e)对数。使用ROUND_HALF_EVEN舍入模式正确舍入结果。
    log10context = None 
    返回操作数的十位对数。使用ROUND_HALF_EVEN舍入模式正确舍入结果。
    logbcontext = None 
    对于非零数字,将其操作数的调整指数作为 Decimal实例返回。如果操作数为零,则 Decimal('-Infinity')返回并DivisionByZero引发标志。如果操作数是无穷大,则Decimal('Infinity')返回。
    logical_and其他context = None 
    logical_and()是一个逻辑操作,它采用两个逻辑操作数(参见逻辑操作数)。结果是and两个操作数的数字方式。
    logical_invertcontext = None 
    logical_invert()是一个逻辑操作。结果是操作数的数字反转。
    logical_or其他context = None 
    logical_or()是一个逻辑操作,它采用两个逻辑操作数(参见逻辑操作数)。结果是or两个操作数的数字方式。
    logical_xor其他context = None 
    logical_xor()是一个逻辑操作,它采用两个逻辑操作数(参见逻辑操作数)。结果是数字排他或两个操作数。
    max其他context = None 
    像不同的是在返回之前和施加的上下文舍入规则值用信号通知或忽略(取决于上下文以及它们是否信令或安静)。max(self, other)NaN
    max_mag其他context = None 
    max()方法类似,但使用操作数的绝对值进行比较。
    min其他context = None 
    像不同的是在返回之前和施加的上下文舍入规则值用信号通知或忽略(取决于上下文以及它们是否信令或安静)。min(self, other)NaN
    min_mag其他context = None 
    min()方法类似,但使用操作数的绝对值进行比较。
    next_minuscontext = None 
    返回给定上下文中可表示的最大数字(如果没有给出上下文,则返回当前线程的上下文中),该数字小于给定的操作数。
    next_pluscontext = None 
    返回在给定上下文中(或者在没有给出上下文的情况下在当前线程的上下文中)可表示的最小数字,该数字大于给定操作数。
    next_toward其他context = None 
    如果两个操作数不相等,则在第二个操作数的方向上返回最接近第一个操作数的数字。如果两个操作数在数值上相等,则返回第一个操作数的副本,其符号设置为与第二个操作数的符号相同。
    normalizecontext = None 
    通过剥离最右边的尾随零并将任何结果转换为等于,Decimal('0')来 标准化数字Decimal('0e0')。用于为等价类的属性生成规范值。例如,Decimal('32.100')与 Decimal('0.321000e+2')两个正常化为等效值Decimal('32.1')
    number_classcontext = None 
    返回描述操作数的字符串。返回的值是以下十个字符串之一。
    • "-Infinity",表明操作数为负无穷大。
    • "-Normal",表示操作数是负正常数。
    • "-Subnormal",表明操作数是负数和次正规。
    • "-Zero",表明操作数是负零。
    • "+Zero",表明操作数是正零。
    • "+Subnormal",表明操作数是正的和低于正常的。
    • "+Normal",表示操作数是正的正常数。
    • "+Infinity",表明操作数是正无穷大。
    • "NaN",表明操作数是一个安静的NaN(非数字)。
    • "sNaN",表明操作数是信令NaN。
    quantizeexprounding = Nonecontext = None 
    舍入后返回一个等于第一个操作数的值,并具有第二个操作数的指数。
    1. >>> Decimal('1.41421356').quantize(Decimal('1.000'))
    2. Decimal('1.414')

    与其他操作不同,如果量化操作之后的系数的长度将大于精度,则用 InvalidOperation信号通知a。这保证了,除非存在错误条件,否则量化指数总是等于右手操作数的指数。

    与其他操作不同,量化从不发出信号下溢,即使结果是低于正常且不精确的。

    如果第二个操作数的指数大于第一个操作数的指数,则可能需要进行舍入。在这种情况下,舍入模式由rounding给定的参数确定,否则由给定的 context参数确定; 如果没有给出参数,则使用当前线程的上下文的舍入模式。

    只要结果指数大于Emax或小于,就会返回错误 Etiny

    radix
    返回Decimal(10)Decimal 类所做算术的基数(基数)。包括与规范的兼容性。
    remainder_near其他context = None 
    从分返回,其余通过其他。这不同之处在于 选择余数的符号以使其绝对值最小化。更确切地说,返回值是 其中最接近的精确值的整数,如果两个整数都同样接近,则即使一个选择。self otherself *othernself other

    如果结果为零,那么它的符号将是自我的符号。

    1. >>> Decimal(18).remainder_near(Decimal(10))
    2. Decimal('-2')
    3. >>> Decimal(25).remainder_near(Decimal(10))
    4. Decimal('5')
    5. >>> Decimal(35).remainder_near(Decimal(10))
    6. Decimal('-5')
    rotate其他context = None 
    返回将第一个操作数的数字旋转第二个操作数指定的量的结果。第二个操作数必须是-precision到precision范围内的整数。第二个操作数的绝对值给出了要旋转的位数。如果第二个操作数为正,则向左旋转; 否则轮换到右边。如果需要,第一个操作数的系数在左侧填充,零长度精度。第一个操作数的符号和指数不变。
    same_quantum其他context = None 
    测试自我和他人是否具有相同的指数或两者是否相同 NaN

    此操作不受上下文影响且安静:不更改任何标志且不执行舍入。作为例外,如果无法准确转换第二个操作数,则C版本可能会引发InvalidOperation

    scaleb其他context = None 
    返回第一个操作数,指数由第二个调整。等价地,返回第一个操作数乘以10**other。第二个操作数必须是整数。
    shift其他context = None 
    返回将第一个操作数的数字移位第二个操作数指定的数量的结果。第二个操作数必须是-precision到precision范围内的整数。第二个操作数的绝对值给出了要移位的位数。如果第二个操作数为正,则向左移动; 否则转移就在右边。转换为系数的数字为零。第一个操作数的符号和指数不变。
    sqrtcontext = None 
    将参数的平方根返回到完全精度。
    to_eng_stringcontext = None 
    如果需要指数,则使用工程符号转换为字符串。

    工程符号的指数是3的倍数。这可以在小数点左边留下最多3位数,并且可能需要添加一个或两个尾随零。

    例如,这转换Decimal('123E+1')Decimal('1.23E+3')

    to_integral舍入=无上下文=无
    to_integral_value()方法相同。to_integral 保留该名称是为了与旧版本兼容。
    to_integral_exact舍入=无上下文=无
    舍入到最接近的整数,发信号Inexact或 Rounded在适当的情况下进行舍入。舍入模式由rounding给定的参数确定,否则由给定的确定 context。如果两个参数均未给出,则使用当前上下文的舍入模式。
    to_integral_value舍入=无上下文=无
    舍入到最接近的整数,没有信号Inexact或 Rounded。如果给出,则应用舍入 ; 否则,在提供的上下文或当前上下文中使用舍入方法。

    逻辑操作数

    logical_and()logical_invert()logical_or(),和logical_xor()方法,希望他们的论点是合乎逻辑的操作数。一个合乎逻辑的操作数是一个Decimal实例,其指数和符号均为零,而其数字都是要么 01

    上下文对象

    上下文是算术运算的环境。它们控制精度,设置舍入规则,确定哪些信号被视为异常,并限制指数的范围。

    每个线程都有自己的当前上下文,可以使用getcontext()setcontext()函数访问或更改它们 :

    decimal.getcontext
    返回活动线程的当前上下文。
    decimal.setcontext
    将活动线程的当前上下文设置为c

    您还可以使用with语句和localcontext() 函数临时更改活动上下文。

    decimal.localcontextctx =无
    返回一个上下文管理器,它将活动线程的当前上下文设置为输入with-statement时的ctx副本,并在退出with-statement时恢复上一个上下文。如果未指定上下文,则使用当前上下文的副本。

    例如,以下代码将当前小数精度设置为42位,执行计算,然后自动恢复以前的上下文:

    1. from decimal import localcontext
    2. with localcontext() as ctx:
    3. ctx.prec = 42 # Perform a high precision calculation
    4. s = calculate_something()
    5. s = +s # Round the final result back to the default precision

    也可以使用Context下面描述的构造函数创建新的上下文。此外,该模块提供了三个预先制作的上下文:

    decimal.BasicContext
    这是由通用十进制算术规范定义的标准上下文。精度设定为9。舍入设置为 ROUND_HALF_UP。所有标志都被清除。除了,和 之外Inexact,所有陷阱都被启用(视为例外)。RoundedSubnormal

    由于启用了许多陷阱,因此该上下文对于调试很有用。

    decimal.ExtendedContext
    这是由通用十进制算术规范定义的标准上下文。精度设定为9。舍入设置为 ROUND_HALF_EVEN。所有标志都被清除。没有启用陷阱(因此在计算期间不会引发异常)。

    由于陷阱已禁用,因此此上下文对于希望具有结果值NaNInfinity代替引发异常的应用程序非常有用。这允许应用程序在存在条件的情况下完成运行,否则将停止程序。

    decimal.DefaultContext
    Context构造函数将此上下文用作新上下文的原型。更改字段(此类精度)具有更改Context构造函数创建的新上下文的默认值的效果。

    此上下文在多线程环境中最有用。在线程启动之前更改其中一个字段会产生设置系统范围默认值的效果。建议不要在线程启动后更改字段,因为它需要线程同步以防止竞争条件。

    在单线程环境中,最好不要使用此上下文。相反,只需如下所述明确创建上下文。

    默认值是prec28, roundingROUND_HALF_EVEN,并启用陷阱OverflowInvalidOperationDivisionByZero

    除了三个提供的上下文之外,还可以使用Context构造函数创建新的上下文 。

    class decimal.Contextprec = Nonerounding = NoneEmin = NoneEmax = Nonecapitals = Noneclamp = Noneflags = Nonetraps = None 
    创建一个新的上下文。如果未指定字段或是None,则从中复制默认值DefaultContext。如果 未指定flags字段None,则清除所有标志。

    prec是[ 1MAX_PREC] 范围内的整数,用于设置上下文中算术运算的精度。

    舍入方法是在一节中列出的一个常量 舍入模式。

    陷阱标志字段列出任何信号进行设置。通常,新的上下文应该只设置陷阱并保持标志清晰。

    额敏的Emax字段指定允许的指数外部界限整数。Emin必须在范围[ MIN_EMIN0]中, Emax在[ 0MAX_EMAX] 范围内。

    首都字段是01(缺省值)。如果设置为 1,则指数用大写字母打印E; 否则,使用小写eDecimal('6.02e+23')

    所述夹具字段是0(缺省值)或1。如果设置为1,则 在此上下文中可表示eDecimal实例的指数严格限制在该范围内。如果是 那么弱的条件成立:调整后的指数情况最多。当是 ,大量正常数量将在可能情况下,具有其指数降低,并且添加到其系数的零的相应数量的,为了适应指数限制; 这会保留数字的值,但会丢失有关重要尾随零的信息。例如:Emin prec <= <= Emax prec 10DecimalEmax1

    1. >>>
    2. >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999')
    3. Decimal('1.23000E+999')

    钳位的值1允许与IEEE 754中指定的固定宽度的小数交换格式的兼容性。

    Context类定义了几个通用的方法以及大量直接在特定情况下做算术的方法。另外,对于Decimal上述每种方法(除了adjusted()as_tuple()方法之外),存在相应的Context方法。例如,对于Context 实例CDecimal实例xC.exp(x)等同于x.exp(context=C)。每个Context方法都接受一个接受intDecimal实例的Python整数(实例)。

    clear_flags
    将所有标志重置为0
    clear_traps
    将所有陷阱重置为0

    版本3.3中的新功能。

    copy
    返回上下文的副本。
    copy_decimalnum 
    返回Decimal实例num的副本。
    create_decimalnum 
    num创建一个新的Decimal实例,但使用self作为上下文。与Decimal构造函数不同,上下文精度,舍入方法,标志和陷阱应用于转换。

    这很有用,因为常量的精度通常高于应用程序所需的精度。另一个好处是,舍入可立即消除超出当前精度的数字的意外影响。在以下示例中,使用未接地输入意味着向求和添加零可以更改结果:

    1. >>> getcontext().prec = 3
    2. >>> Decimal('3.4445') + Decimal('1.0023')
    3. Decimal('4.45')
    4. >>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')
    5. Decimal('4.44')

    此方法实现IBM规范的to-number操作。如果参数是字符串,则不允许使用前导或尾随空格或下划线。

    create_decimal_from_float
    从float f创建一个新的Decimal实例,但使用self 作为上下文进行舍入。与Decimal.from_float()类方法不同,上下文精度,舍入方法,标志和陷阱应用于转换。
    1. >>> context = Context(prec=5, rounding=ROUND_DOWN)
    2. >>> context.create_decimal_from_float(math.pi)
    3. Decimal('3.1415')
    4. >>> context = Context(prec=5, traps=[Inexact])
    5. >>> context.create_decimal_from_float(math.pi)
    6. Traceback (most recent call last):
    7. ...
    8. decimal.Inexact: None

    3.1版中的新功能。

    Etiny
    返回一个值,该值等于subnormal结果的最小指数值。发生下溢时,指数设置为。Emin prec 1Etiny
    Etop
    返回等于的值。Emax prec 1

    处理小数的常用方法是创建Decimal 实例,然后应用在活动线程的当前上下文中发生的算术运算。另一种方法是使用上下文方法在特定上下文中进行计算。这些方法与Decimal课程类似,仅在此处简要介绍。

    abs
    返回x的绝对值。
    addx
    返回xy的总和。
    canonical
    返回相同的Decimal对象x
    comparex
    在数字上比较xy
    compare_signalx
    以数字方式比较两个操作数的值。
    compare_totalx
    使用它们的抽象表示比较两个操作数。
    compare_total_magx
    使用它们的抽象表示比较两个操作数,忽略符号。
    copy_abs
    返回x的副本,其符号设置为0。
    copy_negate
    返回带有符号反转的x的副本。
    copy_signx
    将符号从y复制到x
    dividex
    返回x除以y
    divide_intx
    返回x除以y,截断为整数。
    divmodx
    除以两个数字并返回结果的整数部分。
    exp
    返回e ** x
    fmaxy
    返回x乘以y加上z
    is_canonical
    True如果x是规范的,则返回; 否则返回False
    is_finite
    True如果x是有限的则返回; 否则返回False
    is_infinite
    True如果x是无穷大则返回; 否则返回False
    is_nan
    True如果x是qNaN或sNaN则返回; 否则返回False
    is_normal
    True如果x是正常数,则返回; 否则返回False
    is_qnan
    True如果x是一个安静的NaN,则返回; 否则返回False
    is_signed
    True如果x为负,则返回; 否则返回False
    is_snan
    True如果x是信令NaN,则返回; 否则返回False
    is_subnormal
    True如果x是次正规则返回; 否则返回False
    is_zero
    True如果x为零则返回; 否则返回False
    ln
    返回x的自然(基数e)对数。
    log10
    返回x的基数10对数。
    logb
    返回操作数的MSD幅度的指数。
    logical_andx
    应用逻辑运算在每个操作数的数字之间。
    logical_invert
    反转x中的所有数字。
    logical_orx
    应用逻辑运算在每个操作数的数字之间。
    logical_xorx
    在每个操作数的数字之间应用逻辑运算xor
    maxx
    以数字方式比较两个值并返回最大值。
    max_magx
    将数值与其符号忽略进行比较。
    minx
    以数字方式比较两个值并返回最小值。
    min_magx
    将数值与其符号忽略进行比较。
    minus
    减去对应于Python中的一元前缀减运算符。
    multiplyx
    返回xy的乘积。
    next_minus
    返回小于x的最大可表示数字。
    next_plus
    返回大于x的最小可表示数字。
    next_towardx
    返回最接近x的数字,朝y方向。
    normalize
    x缩减为最简单的形式。
    number_class
    返回x类的指示。
    plus
    Plus对应于Python中的一元前缀加运算符。此操作应用上下文精度和舍入,因此它不是标识操作。
    powerxymodulo =无
    返回x给力y,降低模modulo如果给。

    有两个参数,计算x**y。如果x是否定的则y 必须是积分。结果将是不精确的,除非y是积分且结果是有限的并且可以精确地以’精确’数字表示。使用上下文的舍入模式。结果总是在Python版本中正确舍入。

    版本3.3中更改: C模块根据power()正确舍入 exp()ln()函数计算。结果是明确定义的,但只是“几乎总是正确舍入”。

    有三个参数,计算。对于三参数形式,对参数的以下限制成立:(x**y) modulo

    • 这三个论点必须是不可分割的
    • y 必须是非负的
    • 至少一个xy必须非零
    • modulo 必须非零并且最多具有“精确”数字

    得到的值等于通过无界精度计算得到的值,但计算效率更高。结果的指数是零,不管的指数,和。结果总是精确的。Context.power(x, y, modulo)(x**y) moduloxymodulo

    quantizex
    返回等于x(舍入)的值,其指数为y
    radix
    只返回10,因为这是十进制,:)
    remainderx
    返回整数除法的余数。

    结果的符号(如果非零)与原始股息的符号相同。

    remainder_nearx
    返回,其中n是最接近精确值的整数(如果结果为0则其符号将是x的符号)。ny
    rotatex
    返回xy次的旋转副本。
    same_quantumx
    True如果两个操作数具有相同的指数,则返回。
    scalebx
    添加第二个值后,返回第一个操作数。
    shiftx
    返回xy次的移位副本。
    sqrt
    非负数的平方根到上下文精度。
    subtractx
    返回xy之间的差异。
    to_eng_string
    如果需要指数,则使用工程符号转换为字符串。

    工程符号的指数是3的倍数。这可以在小数点左边留下最多3位数,并且可能需要添加一个或两个尾随零。

    to_integral_exact
    舍入为整数。
    to_sci_string
    使用科学计数法将数字转换为字符串。

    常数

    本节中的常量仅与C模块相关。它们也包含在纯Python版本中以实现兼容性。

     32位64位
    decimal.MAX_PREC
    425000000 999999999999999999
    decimal.MAX_EMAX
    425000000 999999999999999999
    decimal.MIN_EMIN
    -425000000 -999999999999999999
    decimal.MIN_ETINY
    -849999999 -1999999999999999997
    decimal.HAVE_THREADS
    默认值为True。如果Python是在没有线程的情况下编译的,那么C版本会自动禁用昂贵的线程本地上下文机制。在这种情况下,值是False

    舍入模式

    decimal.ROUND_CEILING
    转向Infinity
    decimal.ROUND_DOWN
    向零回合。
    decimal.ROUND_FLOOR
    转向-Infinity
    decimal.ROUND_HALF_DOWN
    绕到最近,关系朝零。
    decimal.ROUND_HALF_EVEN
    舍入到最接近的关系到最接近的整数。
    decimal.ROUND_HALF_UP
    绕到最近的领带远离零。
    decimal.ROUND_UP
    远离零。
    decimal.ROUND_05UP
    如果在向零舍入后的最后一个数字将为0或5,则从零开始舍入; 否则向零舍入。

    信号

    信号表示计算期间出现的条件。每个对应一个上下文标志和一个上下文陷阱启用器。

    只要遇到条件,就会设置上下文标志。在计算之后,可以检查标志以用于信息目的(例如,以确定计算是否准确)。检查标志后,确保在开始下一次计算之前清除所有标志。

    如果为信号设置了上下文的陷阱启用程序,则该条件会引发Python异常。例如,如果DivisionByZero设置了陷阱,则DivisionByZero在遇到该条件时会引发异常。

    decimal.Clamped
    改变指数以适合表示约束。

    通常,当指数超出上下文EminEmax限制时发生钳位 。如果可能,通过向系数添加零来减小指数以适应。

    decimal.DecimalException
    其他信号的基类和。的子类ArithmeticError
    decimal.DivisionByZero
    用零表示非无限数的除法。

    可以通过除法,模除法或将数字提升到负幂时发生。如果此信号未被捕获,则返回Infinity或 -Infinity使用由计算输入确定的符号。

    decimal.Inexact
    表示发生了舍入,结果不准确。

    在舍入期间丢弃非零数字时的信号。返回舍入结果。信号标志或陷阱用于检测结果何时不准确。

    decimal.InvalidOperation
    执行了无效操作。

    表示请求的操作没有意义。如果没有被困,退货NaN。可能的原因包括:

    1. Infinity - Infinity
    2. 0 * Infinity
    3. Infinity / Infinity
    4. x % 0
    5. Infinity % x
    6. sqrt(-x) and x > 0
    7. 0 ** 0
    8. x ** (non-integer)
    9. x ** Infinity
    decimal.Overflow
    数值溢出。

    表示指数大于Emax舍入后的指数。如果没有被捕获,结果取决于舍入模式,向内拉到最大可表示的有限数或向外舍入到Infinity。在这两种情况下,InexactRounded 也发出信号。

    decimal.Rounded
    尽管可能没有信息丢失,但仍发生了舍入。

    四舍五入丢弃数字时发出信号; 即使这些数字为零(例如舍入5.005.0)。如果没有被捕获,则返回结果不变。该信号用于检测有效数字的丢失。

    decimal.Subnormal
    指数低于Emin四舍五入之前。

    当运算结果为低于正常值时(指数太小)发生。如果没有被捕获,则返回结果不变。

    decimal.Underflow
    数值下溢,结果舍入为零。

    通过舍入将次正规结果推到零时发生。Inexact 并且Subnormal还发出信号。

    decimal.FloatOperation
    为混合浮点数和小数点启用更严格的语义。

    如果信号没有被捕获(默认),则在Decimal构造函数 create_decimal()和所有比较运算符中允许混合浮点数和小数。转换和比较都是准确的。通过FloatOperation在上下文标志中设置,可以静默记录任何混合操作的发生。使用from_float() 或create_decimal_from_float()不设置标志的显式转换。

    否则(信号被捕获),只有相等比较和显式转换是静默的。所有其他混业经营提高FloatOperation

    下表总结了信号的层次结构:

    1. exceptions.ArithmeticError(exceptions.Exception)
    2. DecimalException
    3. Clamped
    4. DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
    5. Inexact
    6. Overflow(Inexact, Rounded)
    7. Underflow(Inexact, Rounded, Subnormal)
    8. InvalidOperation
    9. Rounded
    10. Subnormal
    11. FloatOperation(DecimalException, exceptions.TypeError)

    浮点笔记

    以更高的精度减轻舍入误差

    十进制浮点的使用消除了十进制表示错误(使得可以0.1准确表示); 但是,当非零数字超过固定精度时,某些操作仍会产生舍入误差。

    通过增加或减少几乎抵消的量可以放大舍入误差的影响,从而导致重要性的损失。Knuth提供了两个指导性示例,其中精度不足的舍入浮点算法会导致加法的关联和分布属性的细分:

    1. # Examples from Seminumerical Algorithms, Section 4.2.2.
    2. >>> from decimal import Decimal, getcontext
    3. >>> getcontext().prec = 8
    4. >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
    5. >>> (u + v) + w
    6. Decimal('9.5111111')
    7. >>> u + (v + w)
    8. Decimal('10')
    9. >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
    10. >>> (u*v) + (u*w)
    11. Decimal('0.01')
    12. >>> u * (v+w)
    13. Decimal('0.0060000')

    decimal模块可以通过充分扩展精度来恢复身份,以避免重要性的损失:

    1. >>> getcontext().prec = 20
    2. >>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
    3. >>> (u + v) + w
    4. Decimal('9.51111111')
    5. >>> u + (v + w)
    6. Decimal('9.51111111')
    7. >>>
    8. >>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
    9. >>> (u*v) + (u*w)
    10. Decimal('0.0060000')
    11. >>> u * (v+w)
    12. Decimal('0.0060000')

    特殊值

    对于数字系统decimal模块提供了特殊的值,包括NaNsNaN-InfinityInfinity,和两个零,+0-0

    无限可以直接构建: Decimal('Infinity')。而且,当DivisionByZero信号没有被捕获时,它们可以由零除以产生。同样,当Overflow信号没有被捕获时,无限度可能是由于四舍五入超出最大可表示数的极限。

    无穷大是有符号的(仿射),可用于算术运算,它们被视为非常大的,不确定的数字。例如,向无穷大添加常数会产生另一个无限结果。

    某些操作是不确定的并返回NaN,或者如果 InvalidOperation信号被捕获,则引发异常。例如, 0/0返回NaN表示“不是数字”。这种变化 NaN是安静的,一旦创建,将流经其他计算总是导致另一个NaN。此行为对于偶尔会丢失输入的一系列计算非常有用 – 它允许计算继续进行,同时将特定结果标记为无效。

    一种变体是sNaN在每次操作后发出信号而不是保持安静。当无效结果需要中断特殊处理的计算时,这是一个有用的返回值。

    Python的比较运算符的行为在NaN涉及到a时会有点令人惊讶 。对其中一个操作数是安静或信号的相等性的测试NaN总是返回False(即使在做 Decimal('NaN')==Decimal('NaN'))时,对不等式的测试总是返回 True。尝试使用任何比较两个小数<, <=>>=运营商将提高InvalidOperation信号如果操作数是一个NaN,并返回False如果这个信号没有被限制。注意,通用十进制算术规范没有规定直接比较的行为; 这些涉及a的比较规则NaN取自IEEE 854标准(参见5.7节中的表3)。为确保严格遵守标准,请使用compare() 和compare-signal()方法。

    带符号的零可以来自下溢的计算。如果计算执行得更精确,它们会保留可能产生的符号。由于它们的大小为零,因此正零和负零都被视为相等,并且它们的符号是信息性的。

    除了两个明显但相等的带符号的零之外,还有各种零的表示,具有不同的精度但值相等。这需要一些习惯。对于习惯于规范化浮点表示的眼睛,以下计算返回的值等于零并不是很明显:

    1. >>> 1 / Decimal('Infinity')
    2. Decimal('0E-1000026')

    使用线程

    getcontext()函数Context为每个线程访问不同的对象。具有单独的线程上下文意味着线程可以进行更改(例如getcontext().prec=10)而不会干扰其他线程。

    同样,该setcontext()函数自动将其目标分配给当前线程。

    如果setcontext()之前没有调用过getcontext(),那么 getcontext()将自动创建一个新的上下文以供在当前线程中使用。

    新上下文从名为DefaultContext的原型上下文中复制。要控制默认值以便每个线程在整个应用程序中使用相同的值,请直接修改DefaultContext对象。这应该任何线程启动之前完成 这样线程调用之间就不会出现竞争条件getcontext()。例如:

    1. # Set applicationwide defaults for all threads about to be launched
    2. DefaultContext.prec = 12
    3. DefaultContext.rounding = ROUND_DOWN
    4. DefaultContext.traps = ExtendedContext.traps.copy()
    5. DefaultContext.traps[InvalidOperation] = 1
    6. setcontext(DefaultContext)
    7. # Afterwards, the threads can be started
    8. t1.start()
    9. t2.start()
    10. t3.start()
    11. . . .

    演示

    以下是一些用作实用程序功能的方法,并演示了使用Decimal该类的方法:

    1. def moneyfmt(value, places=2, curr='', sep=',', dp='.',
    2. pos='', neg='-', trailneg=''):
    3. """Convert Decimal to a money formatted string.
    4. places: required number of places after the decimal point
    5. curr: optional currency symbol before the sign (may be blank)
    6. sep: optional grouping separator (comma, period, space, or blank)
    7. dp: decimal point indicator (comma or period)
    8. only specify as blank when places is zero
    9. pos: optional sign for positive numbers: '+', space or blank
    10. neg: optional sign for negative numbers: '-', '(', space or blank
    11. trailneg:optional trailing minus indicator: '-', ')', space or blank
    12. >>> d = Decimal('-1234567.8901')
    13. >>> moneyfmt(d, curr='$')
    14. '-$1,234,567.89'
    15. >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
    16. '1.234.568-'
    17. >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
    18. '($1,234,567.89)'
    19. >>> moneyfmt(Decimal(123456789), sep=' ')
    20. '123 456 789.00'
    21. >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
    22. '<0.02>'
    23. """
    24. q = Decimal(10) ** -places # 2 places --> '0.01'
    25. sign, digits, exp = value.quantize(q).as_tuple()
    26. result = []
    27. digits = list(map(str, digits))
    28. build, next = result.append, digits.pop
    29. if sign:
    30. build(trailneg)
    31. for i in range(places):
    32. build(next() if digits else '0')
    33. if places:
    34. build(dp)
    35. if not digits:
    36. build('0')
    37. i = 0
    38. while digits:
    39. build(next())
    40. i += 1
    41. if i == 3 and digits:
    42. i = 0
    43. build(sep)
    44. build(curr)
    45. build(neg if sign else pos)
    46. return ''.join(reversed(result))
    47. def pi():
    48. """Compute Pi to the current precision.
    49. >>> print(pi())
    50. 3.141592653589793238462643383
    51. """
    52. getcontext().prec += 2 # extra digits for intermediate steps
    53. three = Decimal(3) # substitute "three=3.0" for regular floats
    54. lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
    55. while s != lasts:
    56. lasts = s
    57. n, na = n+na, na+8
    58. d, da = d+da, da+32
    59. t = (t * n) / d
    60. s += t
    61. getcontext().prec -= 2
    62. return +s # unary plus applies the new precision
    63. def exp(x):
    64. """Return e raised to the power of x. Result type matches input type.
    65. >>> print(exp(Decimal(1)))
    66. 2.718281828459045235360287471
    67. >>> print(exp(Decimal(2)))
    68. 7.389056098930650227230427461
    69. >>> print(exp(2.0))
    70. 7.38905609893
    71. >>> print(exp(2+0j))
    72. (7.38905609893+0j)
    73. """
    74. getcontext().prec += 2
    75. i, lasts, s, fact, num = 0, 0, 1, 1, 1
    76. while s != lasts:
    77. lasts = s
    78. i += 1
    79. fact *= i
    80. num *= x
    81. s += num / fact
    82. getcontext().prec -= 2
    83. return +s
    84. def cos(x):
    85. """Return the cosine of x as measured in radians.
    86. The Taylor series approximation works best for a small value of x.
    87. For larger values, first compute x = x % (2 * pi).
    88. >>> print(cos(Decimal('0.5')))
    89. 0.8775825618903727161162815826
    90. >>> print(cos(0.5))
    91. 0.87758256189
    92. >>> print(cos(0.5+0j))
    93. (0.87758256189+0j)
    94. """
    95. getcontext().prec += 2
    96. i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
    97. while s != lasts:
    98. lasts = s
    99. i += 2
    100. fact *= i * (i-1)
    101. num *= x * x
    102. sign *= -1
    103. s += num / fact * sign
    104. getcontext().prec -= 2
    105. return +s
    106. def sin(x):
    107. """Return the sine of x as measured in radians.
    108. The Taylor series approximation works best for a small value of x.
    109. For larger values, first compute x = x % (2 * pi).
    110. >>> print(sin(Decimal('0.5')))
    111. 0.4794255386042030002732879352
    112. >>> print(sin(0.5))
    113. 0.479425538604
    114. >>> print(sin(0.5+0j))
    115. (0.479425538604+0j)
    116. """
    117. getcontext().prec += 2
    118. i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
    119. while s != lasts:
    120. lasts = s
    121. i += 2
    122. fact *= i * (i-1)
    123. num *= x * x
    124. sign *= -1
    125. s += num / fact * sign
    126. getcontext().prec -= 2
    127. return +s

    十进制

    问:输入很麻烦decimal.Decimal('1234.5')。有没有办法在使用交互式解释器时最小化键入?

    答:有些用户将构造函数缩写为一个字母:

    1. >>> D = decimal.Decimal
    2. >>> D('1.23') + D('3.45')
    3. Decimal('4.68')

    问:在具有两个小数位的定点应用程序中,某些输入有许多位置并需要舍入。其他人不应该有多余的数字,需要进行验证。应该使用哪些方法?

    答:该quantize()方法舍入到固定的小数位数。如果Inexact设置了陷阱,它对验证也很有用:

    1. >>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01')
    2. >>> # Round to two places
    3. >>> Decimal('3.214').quantize(TWOPLACES)
    4. Decimal('3.21')
    5. >>> # Validate that a number does not exceed two places
    6. >>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
    7. Decimal('3.21')
    8. >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
    9. Traceback (most recent call last):
    10. ...
    11. Inexact: None

    问:一旦我有有效的两位输入,我如何在整个应用程序中保持该不变量?

    A.加法,减法和乘以整数等运算会自动保留不动点。其他操作,如除法和非整数乘法,将改变小数位数,需要跟quantize()进一步:

    1. >>> a = Decimal('102.72') # Initial fixed-point values
    2. >>> b = Decimal('3.17')
    3. >>> a + b # Addition preserves fixed-point
    4. Decimal('105.89')
    5. >>> a - b
    6. Decimal('99.55')
    7. >>> a * 42 # So does integer multiplication
    8. Decimal('4314.24')
    9. >>> (a * b).quantize(TWOPLACES) # Must quantize non-integer multiplication
    10. Decimal('325.62')
    11. >>> (b / a).quantize(TWOPLACES) # And quantize division
    12. Decimal('0.03')

    在开发定点应用程序时,定义处理该quantize()步骤的函数很方便:

    1. >>> def mul(x, y, fp=TWOPLACES):
    2. ... return (x * y).quantize(fp)
    3. >>> def div(x, y, fp=TWOPLACES):
    4. ... return (x / y).quantize(fp)
    5. >>> mul(a, b) # Automatically preserve fixed-point
    6. Decimal('325.62')
    7. >>> div(b, a)
    8. Decimal('0.03')

    问:有很多方法可以表达相同的价值。数字200,, 200.0002E202E+4在各种精度下都具有相同的值。有没有办法将它们转换为单一可识别的规范值?

    答:该normalize()方法将所有等效值映射到单个代表:

    1. >>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
    2. >>> [v.normalize() for v in values]
    3. [Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]

    问:某些十进制值始终以指数表示法打印。有没有办法获得非指数表示?

    答:对于某些值,指数表示法是表示系数中重要位置数的唯一方法。例如,表达 5.0E+35000保持值不变但不能显示原始的两位重要性。

    如果应用程序不关心跟踪重要性,则很容易删除指数和尾随零,丢失重要性,但保持值不变:

    1. >>> def remove_exponent(d):
    2. ... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
    3. >>> remove_exponent(Decimal('5E+3'))
    4. Decimal('5000')

    问:有没有办法将常规浮点数转换为Decimal

    答:是的,任何二进制浮点数都可以精确地表示为十进制,尽管精确转换可能比直觉建议更精确:

    1. >>> Decimal(math.pi)
    2. Decimal('3.141592653589793115997963468544185161590576171875')

    问:在复杂的计算中,如何确保由于精度不足或舍入异常而未得到虚假结果。

    答:十进制模块可以轻松测试结果。最佳实践是使用更高的精度和各种舍入模式重新运行计算。广泛不同的结果表明精度不足,舍入模式问题,病态输入或数值不稳定的算法。

    问:我注意到上下文精度适用于操作结果,但不适用于输入。在混合不同精度的值时,有什么值得注意的吗?

    答:是的。原则是所有值都被认为是精确的,因此对这些值的算术也是如此。只有结果四舍五入。输入的优势在于“您键入的内容就是您所获得的”。缺点是,如果您忘记输入未被舍入,结果可能看起来很奇怪:

    1. >>> getcontext().prec = 3
    2. >>> Decimal('3.104') + Decimal('2.104')
    3. Decimal('5.21')
    4. >>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
    5. Decimal('5.20')

    解决方案是使用一元加操作来提高精度或强制舍入输入:

    1. >>> getcontext().prec = 3
    2. >>> +Decimal('1.23456789') # unary plus triggers rounding
    3. Decimal('1.23')

    或者,可以使用以下Context.create_decimal()方法在创建时舍入输入 :

    1. >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
    2. Decimal('1.2345')
  • 相关阅读:
    Prometheus+Grafana监控
    交互式查询⼯具Impala
    langsong
    linux awk命令详解
    k8s环境下处理容器时间问题的多种姿势
    Golang数据类型之结构体-下篇
    Syntax Error: TypeError: this.getOptions is not a function报错
    百度地图开发-绘制点线提示框 07
    百度地图开发-与地图的交互功能 06
    百度地图开发-实现离线地图功能 05
  • 原文地址:https://www.cnblogs.com/lincappu/p/13535948.html
Copyright © 2020-2023  润新知