打破常规思维
自由 开放 平等 互助

浅谈python3中的round函数

在很多人眼里,round可能是一个四舍五入函数,但到了python3当中并没有你想的那么简单,这已经不再是一个高精度的四舍五入函数了,可能计算的结果会让你出乎意料。

首先看一段代码:

# coding=utf-8
a = 1.2345
b = 1.23456
c = 1.2335
 
print(str(a) + "取后三位结果: " + str(round(a, 3)))
print(str(b) + "取后三位结果: " + str(round(b, 3)))
print(str(c) + "取后三位结果: " + str(round(c, 3)))

运行结果:
1.2345取后三位结果: 1.234
1.23456取后三位结果: 1.235
1.2335取后三位结果: 1.234


发现python3并没有进行四舍五入,为什么呢?

去翻阅python3的文档,有这么一段话:

values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice.

大概意思是:如果距离两边一样远,会保留到偶数的一边。

比如round(0.5)和round(-0.5)都会保留到0,而round(1.5)会保留到2

那么根据这个解释来讲,a b c的结果都应该是1.234的,但目前就a和c取值正确,b为啥会出现1.235呢?继续往下看

文档里面还写到:

The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. 

大概意思是:这不是个bug,而是大部分情况下小数部分转成二进制后会丢失精度

例如:计算机将1.23456转成二进制,这时候二进制比1.23456略大一丢丢 … (比如1.23456000000000001)

计算机不得不将第四位小数进一处理,导致出现了现在的结果:1.2345

如果还不明白,继续往下看

# coding=utf-8
a = 1.23450000000000
b = 1.23450000000001
c = 1.23449999999999
 
print(str(a) + "取后三位结果: " + str(round(a, 3)))
print(str(b) + "取后三位结果: " + str(round(b, 3)))
print(str(c) + "取后三位结果: " + str(round(c, 3)))

可以不去执行,先自己猜一下结果,然后再去验证

先记住“如果距离两边一样远,会保留到偶数的一边。”这句话,然后往下看:

  • a: 小数第三位往后的值是 0.0005,如果第三位是偶数则丢弃,是奇数则进一,最后发现第三位小数是4,属于偶数。结果是:1.234
  • b: 小数第三位往后的值是 0.00050000000001,并不满足距离两边一样远,进一。结果应该是1.235
  • c: 小数第三位往后的值是 0.00049999999999,并不满足距离两边一样远,舍弃,结果应该是1.234

执行这段python代码,运行结果:

  • 1.2345取后三位结果: 1.234
  • 1.23450000000001取后三位结果: 1.235
  • 1.23449999999999取后三位结果: 1.234

最后:如果对精度要求不大,可以用round函数,但如果有四舍五入的需求且对精度要求高,可以考虑decimal模块。

赞(0) 打赏
未经允许不得转载:时光日记 » 浅谈python3中的round函数

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏