出大事了!0.1 + 0.2 居然不等于 0.3,Python我再也不敢用了…

在这里插入图片描述

那天晚上,我差点以为自己疯了

那天晚上,我写代码写得脑壳有点疼,想偷懒搞点简单的练手题,就随手在Python里敲了一句:

print(0.1 + 0.2 == 0.3)

本来想着随便跑一下,顺便热热键盘。

结果——False???

我一瞬间怀疑人生:我小学数学白学了吗??0.1 + 0.2 还能不等于 0.3?

我愣住了几秒,脑子一边在拼命回忆《十万个为什么》,一边在疯狂怀疑是不是键盘出问题了。


这不是bug,这是浮点数的“老毛病”💣

如果你以前没遇到过这个问题,别慌,其实不是 Python 坏掉了,而是所有编程语言(几乎)都有这个毛病,根源在于:

💡 浮点数在计算机中没法完美表示,尤其是像 0.1、0.2 这种“小数点后看着很乖”的家伙。

来,我举个简单例子,展示一下到底发生了什么:

print(0.1 + 0.2)  # 输出:0.30000000000000004

对,你没看错,0.1 + 0.2 实际结果是 0.30000000000000004

想象一下:

你在某宝下单买两样小商品,一个 0.1 元、一个 0.2 元,按理说总价 0.3 元对吧?结果系统后台一算,说你这笔订单金额不合法,直接拦住了。你一脸懵,客服也搞不清楚,最后发现居然是浮点数精度在搞鬼。

听起来很荒谬,但真相就是这么魔幻。


真相大白:0.1 是个“在二进制里没法好好存”的数字

我们得稍微来点底层知识,不难理解:

0.1、0.2 这些十进制小数,其实在 二进制里是无限循环小数,就像十进制里 1/3 是 0.33333…

计算机又不能真存“无限多位”,只能找个差不多的近似值存起来。

于是就出事了:
你以为你存的是 0.1,实际上你存的是个近似值,大概长这样:

0.1 实际是:0.10000000000000000555...
0.2 实际是:0.20000000000000001110...
加起来就变成了:0.3000000000000000444...

那你再拿这玩意和“你心目中正儿八经的0.3”一比:

0.3 实际是:0.29999999999999998889...

嘿嘿,差了几微粒,Python 一看,嗯你俩不一样,直接给你判 False。


那为啥 1.1 + 1.2 == 2.3 就没问题?

这个就很有趣了。

print(1.1 + 1.2 == 2.3)  # True

很多人看到这段会更困惑:这不双标嘛?

其实不是双标,是因为 1.1 + 1.2 的浮点误差比较小,结果正好和 2.3 的误差差不多方向,Python 一看俩都歪一点,但歪得方向一致,那就算你俩对得上。

你可以理解为:

它们都走偏了,但刚好走偏的路数对上了,大家都往右边歪了一点,于是“装模作样”地对上号了。


真正致命的是:这误差可能影响你的业务逻辑!💥

比如你在做支付判断:

price = 0.1 + 0.2
if price == 0.3:
    print("支付成功!")
else:
    print("金额异常,支付失败!")

你以为你写得挺靠谱,结果用户一付款,系统说金额对不上?

一脸懵逼的客服+崩溃的开发+火冒三丈的用户 = 灾难现场。


那到底哪些数字容易出问题?我该怎么防?

说到底,咱们想知道的无非就是:

👉 哪些数字得小心?
👉 哪些场景最容易翻车?
👉 怎么避免这个坑?

别急,花姐给你梳理一张清单:

哪些数字是“雷区”?🔥

数字类型是否安全
0.1、0.2、0.3❌ 极容易出问题
0.5、0.25、0.75✅ 安全(2 的幂次组合)
整数✅ 完美无瑕
连续累加浮点数❌ 极易误差累积

如果你还是一脸懵逼,不妨把他们改成二进制试试
举例说明一下👇

十进制二进制表示是否安全
0.50.1
0.250.01
0.750.11
0.10.0001100110011…(无限循环)

你容易翻车的实际场景:

场景风险点推荐方案
电商金额判断误差导致金额不符用 Decimal
金融计算(利息、年化收益)误差积累Decimal + round
科学计算归一化误差放大结果偏离用 numpy + isclose
游戏角色坐标坐标抖动错位尽量用整数坐标

正确姿势来了✅

1. 用 Decimal 精准搞定金额:

from decimal import Decimal

a = Decimal('0.1')
b = Decimal('0.2')
c = Decimal('0.3')

print(a + b == c)  # True

字符串传入,完全避免浮点存储误差。


2. 判断浮点是否“足够接近”:math.isclose

import math

print(math.isclose(0.1 + 0.2, 0.3))  # True

这个判断方式才是靠谱的 float 比较方式!


3. 千万别这样比!

if a + b == 0.3:  # ❌ 一定不要这么比

最后说一句

说到底,浮点数的锅,不是Python独有的锅,Java、C++、JavaScript 甚至 Excel 都中这个招。

你不能不信它,但也不能完全信它。

当我们知道它的脾气,就能少踩很多坑。


结尾

就像我写这篇文章的时候,原本只是想分享个“0.1+0.2 != 0.3”的小知识,结果越写越上头,写着写着,我都想写本《浮点数的秘密往事》了……

顺手点赞+在看就是对花姐最大的支持❤️!
关注我,带你少踩十年坑,我们下篇见~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花小姐的春天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值