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

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

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

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

 

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

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

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

a = 0.2
b = 0.1
a + b
0.30000000000000004
(a + b) == 0.3 , a+b

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

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

from decimal import Decimal
a = Decimal('0.2')
b = Decimal('0.1')
a + b
Decimal('0.3')
print(a + b)
0.3
(a + b) == Decimal('0.3')

最佳实践

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

a = 0.2
b = 0.1
c = a + b
print("a+b=", c)
0.30000000000000004
x = abs(c - 0.3)
print("x=", x)
if x < 1e-12 :
    print(True, "相等")
else:
    print(False, "不相等")

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

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

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

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

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值