软件测试学习 之 Python 精确四舍五入



如无特别说明,下文均基于

使用round函数

代码稍作修改,就会发现有问题:

round函数到底出了什么问题/h2>

上有人说,因为在计算机里面,小数是不精确的,例如在计算机中实际上是,所以当你对这个小数精确到小数点后两位的时候,实际上小数点后第三位是,所以四舍五入,因此结果为
这种说法,对了一半。因为并不是所有的小数在计算机中都是不精确的。例如这个小数在计算机中就是精确的,它就是,没有省略后面的值,没有近似,它确确实实就是

但是如果我们在Python中把精确到小数点后两位,那么它的就会变成

为什么在这里了/p>

还有更奇怪的,另一个在计算机里面能够精确表示的小数,我们来看看精确到小数点后两位是多少:

为什么这里又了/p>

因为在Python 3里面,对小数的精确度采用了的方式。

如果你写过大学物理的实验 告,那么你应该会记得老师讲过,直接使用四舍五入,最后的结果可能会偏高。所以需要使用的处理方法。

例如对于一个小数,需要精确到小数点后两位,那么就要看小数点后第三位:

  1. 如果小于5,直接舍去
  2. 如果大于5,直接进位
  3. 如果等于5:
    1. 后面没有数据,且c为,那么不进位,保留c
    2. 后面没有数据,且c为,那么进位,c变成(c + 1)
    3. 如果后面还有非0数字,例如实际上小数为,此时一定要进位,c变成(c + 1)

关于奇进偶舍,有兴趣的同学可以在维基百科搜索这两个词条:

所以,给出的结果如果与你设想的不一样,那么你需要考虑两个原因:

  1. 你的这个小数在计算机中能不能被精确储存果不能,那么它可能并没有达到四舍五入的标准,例如,它的小数点后第三位实际上是,当然会被舍去。
  2. 如果你的这个小数在计算机中能被精确表示,那么,采用的进位机制是,所以这取决于你要保留的那一位,它是奇数还是偶数,以及它的下一位后面还有没有数据。

如何正确进行四舍五入

如果要实现我们数学上的四舍五入,那么就需要使用decimal模块。

如何正确使用decimal模块呢/p>

不要担心看不懂英文,Python已经推出了官方中文文档(有些函数的使用方法还没有翻译完成)。

我们来看一下:https://docs.python.org/zh-cn/3/library/decimal.html#decimal.Decimal.quantize

官方文档给出了具体的写法:

那么我们来测试一下,分别保留两位小数是多少: 

怎么结果和一样们来看看文档中的函数原型和文档说明: 

这里提到了可以通过指定参数来确定进位方式。如果没有指定参数,那么默认使用上下文提供的进位方式。

现在我们来查看一下默认上下文中的进位方式是什么:

实际上就是!如果要指定真正的四舍五入,那么我们需要在中指定进位方式为

现在看起来一切都正常了。
那么会不会有人进一步追问一下,如果Decimal接收的参数不是字符串,而是浮点数会怎么样呢br> 来实验一下:

那是不是说明,在Decimal的第一个参数,可以直接传浮点数呢/p>

我们换一个数来测试一下:

为什么浮点数和字符串,传进去以后,结果不一样/p>

我们继续在文档在寻找答案。

 

官方文档已经很清楚地说明了,如果你传入的参数为浮点数,并且这个浮点值在计算机里面不能被精确存储,那么它会先被转换为一个不精确的二进制值,然后再把这个不精确的二进制值转换为

对于不能精确表示的小数,当你传入的时候,Python在拿到这个数前,这个数就已经被转成了一个不精确的数了。所以你虽然参数传入的是,但是Python拿到的实际上是

但是如果你传入的是字符串,那么Python拿到它的时候,就能知道这是,不会提前被转换为一个不精确的值,所以,建议给的第一个参数传入字符串型的浮点数,而不是直接写浮点数。

总结,如果想实现精确的四舍五入,代码应该这样写:

 特别注意,一旦要做精确计算,那么就不应该再单独使用浮点数,而是应该总是使用。否则,当你赋值的时候,精度已经被丢失了,建议全程使用Decimal举例:

最后,如果有同学想知道为什么0.125和0.375能被精确的储存,而1.115、11.245不能被精确储存,请在这篇文章下面留言,如果想知道的同学多,我就写一篇文章来说明。

文章知识点与官方知识档案匹配,可进一步学习相关知识Python入门技能树首页概览212636 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年2月28日
下一篇 2019年2月28日

相关推荐