解决python运算结果是浮点数

  • Question
  • Reason
  • 所以到底为什么不是0.1而是0.9999....呢?
  • Solution
  • NO1.对于某些实际问题可使用round()函数进行保留
  • NO2.对于数值运算可以使用Decimal模块


Question

今天在实现一个减法运算print(45.4-2*20)的结果中发现结果是5.399999999999999

Reason

网上查询博客才了解原来是自己啥也不是。。。:

所以到底为什么不是0.1而是0.9999…呢?

因为浮点数在计算机中实际上是以二进制的形式保存的,有些数不精确。

例如:0.1是十进制,转化二进制是无限循环的

1. 方法十进制小数转换成二进制小数的计算方法:采用“乘2取整,顺序排列”法。
具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。
然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。

2. 具体过程:
0.1*2=0.2======取出整数部分0

0.2*2=0.4======取出整数部分0

0.4*2=0.8======取出整数部分0

0.8*2=1.6======取出整数部分1

0.6*2=1.2======取出整数部分1

0.2*2=0.4======取出整数部分0

0.4*2=0.8======取出整数部分0

0.8*2=1.6======取出整数部分1

0.6*2=1.2======取出整数部分1

接下来会无限循环

0.2*2=0.4======取出整数部分0

0.4*2=0.8======取出整数部分0

0.8*2=1.6======取出整数部分1

0.6*2=1.2======取出整数部分1

所以0.1转化成二进制是:0.0 0011 0011 …,而python中是以双精度(64)位来保存浮点数的因此多余的位数会被截掉
因此,python中浮点运算不是直接的运算结果
例如:1.1+2.2不等于3.3

》 》》》》》》所以到底如何解决呢?《《《《《《《
!我找了一些网上的答案,亲测有效

Solution

NO1.对于某些实际问题可使用round()函数进行保留

例如:输入应付金额与实付金额找零

// change零钱  vallist[]面额数组 paper张数
change=round(change-vallist[i]*paper,1)

round(变量,保留位数会四舍五入)

NO2.对于数值运算可以使用Decimal模块

// 需要先导入库
from decimal import Decimal
a=Decimal('1.1')
b=Decimal('2.2')
print(a+b)

如果要控制所有运算可以创建临时上下文环境改变设定,使用with的上下文方式来指定精度ctx.prec

from decimal import Decimal,localcontext
a=Decimal('45.4')
b=Decimal('40')
print(a-b)

with localcontext() as ctx:
    ctx.prec=2
    print(a-b)

5.4
5.4

还有对Decimal这个模块的应用,之后如果碰到我自己还会补充



注明:本文章解决思路参考网上多篇文章,按自己的实际情况尝试整理,仅供参考,如有不当,欢迎评论!