当前位置:   article > 正文

第三十八回 浔阳楼宋江吟反诗 梁山泊戴宗传假信-python执行精确的浮点数计算和等值判断

第三十八回 浔阳楼宋江吟反诗 梁山泊戴宗传假信-python执行精确的浮点数计算和等值判断

李逵用指头就把歌女点晕了,宋江出二十两银子让她爹娘不要再卖唱,嫁个好人。离别的时候,宋江又给了李逵五十两银子。

宋江把一尾鱼送给管营,自己留了一尾吃。因为鱼新鲜,多吃了些,结果四更天就肚子疼拉肚子,一下子病倒了。修养了五七天,宋江就去城里找戴宗,没找到。再去找李逵,没找到。又去找张顺,还是没找到。
宋江就一个人到浔阳楼喝酒散心,不知不觉就喝醉了,乘着酒兴,写下了诗句:自幼曾攻经史,长成亦有权谋。恰如猛虎荒邱,潜伏爪牙忍受。不幸刺文双颊,那堪配在江州!他年若报冤仇,血染浔阳江口!
宋江又写了四句诗:心在山东身在吴,飘蓬江海漫嗟吁。他时若遂凌云志,敢笑黄巢不丈夫!写完之后,又写上“郓城宋江作”。回家一觉睡到第二天大清早,把喝酒写诗的事情全忘记了。

宋江不经意的举动,引来灾祸。编程中,有时候也有被忽视的情况,比如浮点数计算和等值判断:

 

 python执行精确的浮点数计算和等值判断

在Python中,浮点数是通过IEEE 754标准表示的。该标准使用64位(双精度)或32位(单精度)来存储浮点数,其中包括1位符号位、11位指数位和52位尾数位(对于双精度)。由于二进制无法精确表示所有十进制小数,因此在进行浮点数计算时,Python会遇到精度问题。

比如最简单的加法,0.1+0.2 ,竟然不等于0.3 ,而是一个比0.3略大一点点的数,这导致直接判断相等的语句,永远返回是False

  1. a = 0.2
  2. b = 0.1
  3. a + b
  4. 0.30000000000000004
  5. (a + b) == 0.3 , a+b

解决策略与实践:使用Decimal模块

Python标准库中的Decimal模块提供了一个Decimal数据类型,用于进行高精度的十进制浮点数计算。与普通的浮点数相比,Decimal类型可以更加精确地表示和计算十进制小数。

  1. from decimal import Decimal
  2. a = Decimal('0.2')
  3. b = Decimal('0.1')
  4. a + b
  5. Decimal('0.3')
  6. print(a + b)
  7. 0.3
  8. (a + b) == Decimal('0.3')

最佳实践

在实际项目中,可能并不会使用库,常规的解决方法是这样的:尽量不使用浮点数相等判断,所有比较是否相等的地方,都采用判断差值是否在一个可接受的极小值范围之内。比如我们希望精度是1e-12,那么只要两个数的差值小于1e-12,我们就认为两个数相等。

  1. a = 0.2
  2. b = 0.1
  3. c = a + b
  4. print("a+b=", c)
  5. 0.30000000000000004
  6. x = abs(c - 0.3)
  7. print("x=", x)
  8. if x < 1e-12 :
  9. print(True, "相等")
  10. else:
  11. print(False, "不相等")

江州对岸无为军的通判黄文炳,恰巧看到了宋江的诗,将这件事告知了蔡九知府。蔡九知府刚开始不重视,黄文炳说外面的流言,耗国因家木,刀兵点水工;纵横三十六,播乱在山东,就应在宋江身上。耗国因家木,这是宋字,刀兵点水工,这是江字,播乱在山东,郓城就是山东的。

蔡九于是重视起来,让戴宗去捉拿宋江。戴宗稳住众人,做起“神行法”,先人一步找到宋江,出主意让宋江装疯。于是众人回复蔡九知府说原来是个疯子。黄文炳说看笔迹不像疯子,最终宋江被捉,拷打后就招了,被打入死牢。

蔡九写了详细的信让戴宗带给蔡京。半路被梁山朱贵麻翻看到了信,才知道蔡九要害宋江。吴用请了圣手书生萧让和玉臂匠金大坚伪造了蔡京的信,让戴宗送回。戴宗走后,吴用说有个破绽。

欲知后市如何,且听下回分解。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/121656
推荐阅读
相关标签
  

闽ICP备14008679号