# python decimal 精确计算

1.可以传递给Decimal整型或者字符串参数，但不能是浮点数据，因为浮点数据本身就不准确。需要先将浮点数转化为字符串

from decimal import *
print(Decimal(5.55)*100)
print(Decimal('5.55')*100)
print(Decimal('4.20') + Decimal('2.10'))
x = 4.20
y = 3.10
print(Decimal(str(x)) + Decimal(str(y)))
#运行结果分别是：
#554.9999999999999822364316060
#555.00
#6.30
#7.3


2.要从浮点数据转换为Decimal类型

from decimal import *
print(Decimal.from_float(22.222))
#运行结果：22.22200000000000130739863379858434200286865234375


3.通过设定有效数字，限定结果样式：

from decimal import *
getcontext().prec = 5
print(Decimal(1)/Decimal(7))
print(Decimal(1.00)/Decimal(3.0))
#运行结果，五个有效数字：0.14286
#运行结果：0.33333


4.四舍五入，保留几位小数

from decimal import *
print(Decimal('50.5679').quantize(Decimal('0.00')))
#运行结果四舍五入保留了两位小数：50.57


5.Decimal 结果转化为string

from decimal import *
print(str(Decimal('3.40').quantize(Decimal('0.0'))))
#运行结果：3.4


from decimal import *
print(getcontext())  # Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
num,num1 = '12355','123.55'
getcontext().prec = len(num) +2
print(Decimal(num1)*100 == Decimal(num))   #True
getcontext().prec = 3
# todo 如果prec的长度比数字的长度小的话，*100得出的数就不对了
print(Decimal(num1)*100)                   #1.24E+4
print(Decimal(num1))                       #123.55
print(Decimal(num1)*100 == Decimal(num))   #False
print(Decimal(num))                        #12355


6.python decimal.quantize()参数rounding的各参数解释与行为

ROUND_CEILING (towards Infinity),
ROUND_DOWN (towards zero),
ROUND_FLOOR (towards -Infinity),
ROUND_HALF_DOWN (to nearest with ties going towards zero),
ROUND_HALF_EVEN (to nearest with ties going to nearest even integer),
ROUND_HALF_UP (to nearest with ties going away from zero), or
ROUND_UP (away from zero).
ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero)


1）首先给出一组负数的后一位超过5的数据：

from decimal import *

x = Decimal('-3.333333333') + Decimal('-2.222222222')
print(x)   # -5.555555555
print(x.quantize(Decimal('1.0000'), ROUND_HALF_EVEN))    # -5.5556
print(x.quantize(Decimal('1.0000'), ROUND_HALF_DOWN))    # -5.5556
print(x.quantize(Decimal('1.0000'), ROUND_CEILING))      # -5.5555
print(x.quantize(Decimal('1.0000'), ROUND_FLOOR))        # -5.5556
print(x.quantize(Decimal('1.0000'), ROUND_UP))           # -5.5556
print(x.quantize(Decimal('1.0000'), ROUND_DOWN))         # -5.5555


ROUND_HALF_EVEN 和 ROUND_HALF_DOWN：EVEN是quansize的默认设置值，可以通过getcontext()得到，EVEN四舍五入进了一位，DOWN为接近最近的0进了一位。

ROUND_CEILING 和 ROUND_FLOOR：CEILING超过5没有进位是因为它倾向正无穷，FLOOR为了总是变得更小所以进了一位。

ROUND_UP 和 ROUND_DOWN：UP始终进位，DOWN始终不会进位。

2）再多对比一组后一位没有超过5的数据：

from decimal import *

x = Decimal('-3.333333333') + Decimal('-1.111111111')
print(x)   # -4.444444444
print(x.quantize(Decimal('1.0000'), ROUND_HALF_EVEN))    # -4.4444
print(x.quantize(Decimal('1.0000'), ROUND_HALF_DOWN))    # -4.4444
print(x.quantize(Decimal('1.0000'), ROUND_CEILING))      # -4.4444
print(x.quantize(Decimal('1.0000'), ROUND_FLOOR))        # -4.4445
print(x.quantize(Decimal('1.0000'), ROUND_UP))           # -4.4445
print(x.quantize(Decimal('1.0000'), ROUND_DOWN))         # -4.4444


ROUND_HALF_EVEN 和 ROUND_HALF_DOWN：EVEN是quansize的默认设置值，可以通过getcontext()得到，EVEN由于达不到四舍五入所以不进位，DOWN同样也不进位。

ROUND_CEILING 和 ROUND_FLOOR：CEILING倾向正无穷不进位，FLOOR即使没有超过5，但是为了总是变得更小进了一位。

ROUND_UP 和 ROUND_DOWN：UP始终进位，DOWN始终不会进位。

3）正数部分后面数大于5的情况：

from decimal import *

x = Decimal('3.333333333') + Decimal('2.222222222')
print(x)   # 5.555555555
print(x.quantize(Decimal('1.0000'), ROUND_HALF_EVEN))    # 5.5556
print(x.quantize(Decimal('1.0000'), ROUND_HALF_DOWN))    # 5.5556
print(x.quantize(Decimal('1.0000'), ROUND_CEILING))      # 5.5556
print(x.quantize(Decimal('1.0000'), ROUND_FLOOR))        # 5.5555
print(x.quantize(Decimal('1.0000'), ROUND_UP))           # 5.5556
print(x.quantize(Decimal('1.0000'), ROUND_DOWN))         # 5.5555


ROUND_HALF_EVEN 和 ROUND_HALF_DOWN：EVEN是quansize的默认设置值，可以通过getcontext()得到，EVEN由于达到四舍五入所以进位，DOWN同样进位。

ROUND_CEILING 和 ROUND_FLOOR：CEILING正数始终进位，FLOOR在正数则始终不会进位。

ROUND_UP 和 ROUND_DOWN：UP始终进位，DOWN始终不会进位。

4）正数部分后面数小于5的情况：

from decimal import *

x = Decimal('3.333333333') + Decimal('1.111111111')
print(x)   # 4.444444444
print(x.quantize(Decimal('1.0000'), ROUND_HALF_EVEN))    # 4.4444
print(x.quantize(Decimal('1.0000'), ROUND_HALF_DOWN))    # 4.4444
print(x.quantize(Decimal('1.0000'), ROUND_CEILING))      # 4.4445
print(x.quantize(Decimal('1.0000'), ROUND_FLOOR))        # 4.4444
print(x.quantize(Decimal('1.0000'), ROUND_UP))           # 4.4445
print(x.quantize(Decimal('1.0000'), ROUND_DOWN))         # 4.4444


ROUND_HALF_EVEN 和 ROUND_HALF_DOWN：EVEN是quansize的默认设置值，可以通过getcontext()得到，EVEN由于没有达到四舍五入所以不进位，DOWN同样不进位。

ROUND_CEILING 和 ROUND_FLOOR：CEILING正数始终进位，FLOOR在正数则始终不会进位。

ROUND_UP 和 ROUND_DOWN：UP始终进位，DOWN始终不会进位。

07-08 1万+
08-30 4万+
12-05 1658
01-20 808
12-17 4491
10-14 120
08-02 3304
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客