目录
问题
你是否遇到过这样的问题:
然后你开始怀疑人生,究竟是数学老师骗了我,还是计算机骗了我。
答案是,没人骗你,甚至你的数学老师都不曾记得你。
原因
之所以出现这种让人摸不着头脑的问题,是因为人类使用数字的习惯和计算机存储处理数字的方式不同。
“0.1”是十进制数字,计算机存储浮点数要将十进制转为二进制。而在十进制位数有限的数字,转为二进制时,就未必还是有限数字。
同时,因为计算机的存储空间有限,对于无限数字只能近似存储,也就出现了开头的问题。
解决
那该如何避免浮点数进行比较时出现这种状况呢?答案是,不要比较。如何避免买到假货,答案是不要买。这话说的不讲道理,但却无法反驳。
其实说不要比较,是不要用等号去比较,可以换种方式:
isclose函数会根据数字大小,计算一个relative tolerance(相对误差,博主译,未必准确,请自行理解),如果二者之间的距离(差的绝对值)小于relative tolerance,则返回结果为True。
你也可以自定义相对误差数值:
之后,需要用等号比较浮点数的地方,都可以用isclose替代。
当然还有其他替代方式,比如numpy中的allclose等等。这些方式虽然都是近似,但在非精密计算下,完全可以满足我们的需求。
参考
The Right Way to Compare Floats in Python (收录于Pycoder's Weekly #518 March 29, 2022)