IEEE 754浮点数精度揭秘:0.1+0.2为何不等于0.3

1. 从一个让无数人怀疑人生的等式说起

0.1 + 0.2 == 0.3这行代码,如果你在浏览器控制台或者 Python 交互环境里敲下去,返回的结果大概率是一个干脆利落的false。第一次撞见这个现象的人,反应基本分三档:第一档觉得电脑坏了,第二档觉得语言有 bug,第三档开始怀疑自己当年数学是不是白学了。我当年属于第三档,盯着屏幕愣了好一会儿,还特意拿计算器按了一遍确认 0.1 加 0.2 确实等于 0.3。

这个现象不是某个语言的锅,也不是浏览器抽风,它是浮点数在计算机里的二进制表示方式决定的必然结果。JavaScript、Python、Java、C、Go,只要用的是 IEEE 754 标准的双精度浮点数,都会得到同样的答案。换句话说,这不是 bug,是 feature,是计算机在“用有限位表示无限小数”这件事上做出的妥协。

这篇内容我想干的事情很明确:把“为什么 0.1 + 0.2 不等于 0.3”这件事从根上讲透。不是那种“因为浮点数精度问题所以不要用 == 比较”的一句话敷衍,而是真正把十进制小数怎么变成二进制、二进制怎么存进 64 位、误差从哪一步开始产生、为什么有些小数能精确表示有些不能,这一整条链路拆开给你看。看完之后你不仅能给别人讲明白,还能在实际写代码时知道哪些坑要绕、哪些场景必须换方案。

适合谁看?只要写过代码、调过金额计算、做过数据比对的人,都值得花时间把这套逻辑理顺。前端同学处理价格显示、后端同学做订单金额、数据同学做浮点聚合,全都绕不开这个话题。哪怕你只是好奇为什么计算器算得对电脑算不对,这篇也能给你一个交代。

2. 十进制小数转二进制:误差的源头在这里

2.1 整数和小数,转换规则完全不是一回事

要理解误差从哪来,得先搞清楚计算机怎么把十进制小数变成二进制。很多人对二进制转换的印象停留在整数那一套:除 2 取余,倒序排列。比如 13 转二进制,13 除以 2 得 6 余 1,6 除以 2 得 3 余 0,3 除以 2 得 1 余 1,1 除以 2 得 0 余 1,倒着读就是1101。这套方法干净利落,任何整数都能在有限步内转完。

但小数部分完全是另一套逻辑:乘 2 取整,顺序排列。拿 0.625 举例,0.625 乘 2 得 1.25,取整数部分 1;0.25 乘 2 得 0.5,取整数部分 0;0.5 乘 2 得 1.0,取整数部分 1;小数部分变成 0,停止。顺序读下来就是0.101,验证一下:1/2 + 0/4 + 1/8 = 0.5 + 0.125 = 0.625,对上了。

问题就出在这个“停止”上。整数转换一定会停,因为整数除以 2 迟早会到 0。但小数乘 2 不一定停,它可能陷入无限循环。0.625 运气好,三步就结束了。换成 0.1 呢?我们来实际走一遍。

2.2 0.1 的二进制展开:一个无限循环小数

0.1 乘 2 得 0.2,取整 0;0.2 乘 2 得 0.4,取整 0;0.4 乘 2 得 0.8,取整 0;0.8 乘 2 得 1.6,取整 1;0.6 乘 2 得 1.2,取整 1;0.2 乘 2 得 0.4,取整 0……到这里你应该发现了,0.2 又回来了,接下来就是 0.4、0.8、1.6、1.2、0.4 无限循环。

所以 0.1 的二进制是0.000110011001100110011...,其中0011这四位无限重复。用数学语言说,0.1 在二进制下是一个无限循环小数。这跟十进制里 1/3 = 0.3333... 是同一类东西,只不过十进制里循环的是 3,二进制里循环的是 0011。

0.2 呢?0.2 乘 2 得 0.4 取 0,0.4 乘 2 得 0.8 取 0,0.8 乘 2 得 1.6 取 1,0.6 乘 2 得 1.2 取 1,然后 0.2 又回来了。所以 0.2 的二进制是0.001100110011...,循环节同样是 0011,只是起始位置比 0.1 晚一位。

这里有个关键认知:十进制里看起来人畜无害的 0.1 和 0.2,在二进制里都是无限循环小数。而计算机的存储空间是有限的,64 位双精度浮点数能用来存小数部分的位数就那么多,不可能存下无限循环的东西。存不下怎么办?只能截断,只能近似。误差从这一刻就埋下了。

2.3 哪些小数能精确表示,哪些不能

判断一个十进制小数能不能被二进制精确表示,有个简单的规律:看它能不能写成若干个 2 的负整数次幂之和。2 的负整数次幂是 1/2、1/4、1/8、1/16、1/32……也就是 0.5、0.25、0.125、0.0625、0.03125 这些。

0.5 能,就是 1/2。0.25 能,就是 1/4。0.625 能,是 1/2 + 1/8。0.75 能,是 1/2 + 1/4。但 0.1 不能,因为 0.1 等于 1/10,分母 10 含有质因数 5,而 2 的幂次分母只含质因数 2。一个最简分数的分母如果含有 2 以外的质因数,它在二进制下就是无限循环小数。

这个规律可以推广:在 b 进制下能精确表示的最简分数,其分母的质因数必须全部是 b 的质因数。十进制下分母只含 2 和 5 的分数能精确表示,所以 1/2、1/4、1/5、1/8、1/10 都能写成有限小数。二进制下分母只能含 2,所以 1/10 就不行了。

十进制小数二进制表示能否精确表示
0.50.1能
0.250.01能
0.6250.101能
0.10.000110011...不能,无限循环
0.20.001100110...不能,无限循环
0.30.010011001...不能,无限循环

看到这张表你应该明白了,0.1、0.2、0.3 三个数在二进制里全是无限循环小数,计算机存的都是近似值。三个近似值做运算,结果自然也是近似值,两个近似值恰好相等的概率极低。这就是0.1 + 0.2 != 0.3的根本原因。

3. IEEE 754 双精度浮点数:64 位到底怎么分配

3.1 符号位、指数位、尾数位的分工

知道了小数转二进制会出问题,接下来得看计算机具体怎么存。目前主流语言用的都是 IEEE 754 标准的双精度浮点数,总共 64 位,分成三段:

  • 符号位(sign):1 位,0 表示正数,1 表示负数。
  • 指数位(exponent):11 位,用来表示数量级,也就是小数点该往哪挪。
  • 尾数位(fraction/mantissa):52 位,用来存有效数字。

这里有个容易搞混的点:浮点数存的是科学计数法的二进制形式,也就是1.xxxxx × 2^e这种结构。尾数位存的是1.xxxxx里小数点后面的xxxxx部分,那个整数位的 1 是隐含的,不占存储空间。这叫隐含前导 1规则,是 IEEE 754 的一个巧妙设计,相当于白赚一位精度。

指数位不是直接存指数本身,而是存偏移后的值。双精度的偏移量是 1023,也就是说实际指数 e 存进去的时候要加 1023。比如 e = -4,存的就是 1019。这样做的目的是让指数位能表示负数,同时方便硬件比较大小。

3.2 0.1 在 64 位里长什么样

我们来实际算一下 0.1 的存储。0.1 的二进制是0.000110011001100110011...,把它规格化成科学计数法,小数点要右移 4 位,变成1.100110011001100110011... × 2^-4。

指数是 -4,加上偏移 1023 得 1019,转成 11 位二进制是01111111011。尾数部分取1001100110011001100110011001100110011001100110011001,注意这里只取 52 位,后面无限循环的部分被截断了。截断的时候会做舍入,IEEE 754 默认用的是“向偶数舍入”,也就是四舍五入的变种,遇到正好在中间的情况往偶数那边靠。

最终 0.1 在内存里的 64 位是:

0 01111111011 1001100110011001100110011001100110011001100110011001

符号位 0,指数位 01111111011,尾数位 52 位。这个值跟真正的 0.1 之间有一个极小的误差,大约是 5.55e-18 量级。0.2 同理,指数是 -3,尾数也是 0011 循环,同样被截断。

3.3 加法运算时误差是怎么累积的

0.1 和 0.2 各自带着误差存进去,做加法的时候,两个数要先对齐指数。0.1 是 1.xxx × 2^-4,0.2 是 1.xxx × 2^-3,要把 0.1 的尾数右移一位或者把 0.2 的尾数左移一位,让指数一致才能相加。右移的过程中,最低位会被挤出去,又产生一次精度损失。

加完之后的结果再规格化、再舍入,存回 64 位。这一连串操作下来,最终得到的“0.1 + 0.2”的结果,跟真正的 0.3 之间存在一个微小的偏差。在双精度下,这个偏差大约是 5.55e-17 量级。

而 0.3 单独存储的时候,也有自己的舍入误差。两个误差来源不同、大小不同,所以0.1 + 0.2的结果和0.3的存储值不相等。如果你在控制台打印0.1 + 0.2,会看到0.30000000000000004,那个尾巴上的 4 就是误差的可视化体现。

注意:这个 4 不是随便出现的,它是二进制舍入误差在十进制下的投影。不同语言、不同平台打印出来的位数可能略有差异,但底层 64 位表示是一致的。

4. 实际开发中怎么处理浮点数比较

4.1 绝对不能用 == 直接比较

知道了原理,第一条铁律就出来了:永远不要用==或===直接比较两个浮点数。不管是 JavaScript、Python 还是 Java,这条规则都适用。0.1 + 0.2 == 0.3返回 false 只是最经典的例子,实际业务里还有更多隐蔽的坑。

比如判断两个金额是否相等、判断循环是否该结束、判断坐标是否重合,只要涉及浮点数,直接比较都可能出问题。我见过一个真实案例,某系统用浮点数累加计算总价,累加 100 次 0.01,结果跟预期的 1.0 差了 1e-15 量级,导致对账时判定为不一致,排查了大半天才定位到浮点误差。

4.2 用 epsilon 做容差比较

正确的做法是引入一个容差(epsilon),判断两个数的差的绝对值是否小于这个容差:

function nearlyEqual(a, b, epsilon = 1e-9) { return Math.abs(a - b) < epsilon; } nearlyEqual(0.1 + 0.2, 0.3); // true

epsilon 取多大要看业务场景。科学计算可能取 1e-12,普通业务取 1e-9 或 1e-6 都行。原则是:epsilon 要大于你业务中可接受的最大误差,同时小于你业务中需要区分的最小差值。

Python 里可以用math.isclose(),它内部就是做容差比较,还支持相对容差:

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

Java 里可以用Double.compare()配合自定义容差,或者用BigDecimal做精确计算。

4.3 金额计算必须换方案

涉及金额的场景,浮点数绝对不能碰。金额有明确的精度要求(通常到分),而且对账必须分毫不差。这时候要用定点数或者十进制浮点数。

最稳妥的方案是用整数存最小单位。比如金额以分为单位存成整数,1.23 元存成 123 分,所有运算都用整数做,最后显示的时候再除以 100。这样完全避开了浮点误差。

如果语言支持,也可以用专门的十进制类型。Java 的BigDecimal、Python 的decimal.Decimal、C# 的decimal,都是为精确十进制运算设计的。它们内部用十进制存储,能精确表示 0.1、0.2 这些数,代价是运算速度比原生浮点慢不少。

BigDecimal a = new BigDecimal("0.1"); BigDecimal b = new BigDecimal("0.2"); BigDecimal c = a.add(b); // 0.3,精确 System.out.println(c.equals(new BigDecimal("0.3"))); // true

提示:用BigDecimal的时候一定要用字符串构造,用new BigDecimal(0.1)会把浮点误差带进去,等于白用。

方案精度性能适用场景
原生浮点数有误差最快科学计算、图形、非精确场景
epsilon 容差比较可控误差快一般数值比较
整数存最小单位精确快金额、计数
BigDecimal/Decimal精确较慢金融、财务、高精度要求

5. 那些年我踩过的浮点数坑

5.1 循环累加导致的偏差

早年做数据统计,有个需求是把一批小数累加求和。我图省事直接用浮点数循环加,结果加了几万条之后,总和跟用数据库SUM出来的结果对不上。排查半天才发现,数据库内部用的是更高精度的累加,而我这边每加一次都产生一次舍入误差,误差累积起来就明显了。

后来改成先排序再累加,把绝对值小的数先加,能减少大数吃小数的现象。更好的做法是用 Kahan 求和算法,专门补偿浮点累加的误差。再后来涉及金额的场景,直接全换成整数运算,一劳永逸。

5.2 前端显示金额的坑

前端展示金额时,toFixed(2)是常用方法,但它也有坑。(1.005).toFixed(2)返回的是"1.00"而不是"1.01",因为 1.005 在二进制里存的是 1.00499999...,四舍五入自然往下走。这个坑在价格计算里特别致命,用户看到的价格可能少一分钱。

解决办法是后端算好金额再传给前端,前端只负责显示,不做任何金额运算。如果非要在前端算,用整数分做运算,显示时再格式化。

5.3 数据库字段类型选错

数据库里存金额,FLOAT和DOUBLE都是雷。MySQL 的FLOAT精度只有 7 位左右,存大额金额直接丢精度。正确做法是用DECIMAL(m, d),比如DECIMAL(10, 2)表示总共 10 位、小数 2 位,能精确存储金额。

我见过一个项目,订单表金额字段用了DOUBLE,上线半年后对账发现有几笔订单差了一分钱,查了半天才定位到字段类型。改字段类型涉及数据迁移,成本不小,所以这个坑最好在设计阶段就避开。

5.4 常见问题速查表

现象原因解决方案
0.1 + 0.2 != 0.3二进制无法精确表示 0.1 和 0.2用 epsilon 比较或换十进制类型
toFixed 结果不符合预期底层存储值有偏差后端算好再传,或整数运算
累加结果偏差大误差累积Kahan 求和或整数运算
数据库金额对不上字段用了 FLOAT/DOUBLE改用 DECIMAL
大数吃小数指数对齐时小指数被截断排序后累加或提高精度

注意:浮点数的坑不止这些,但核心逻辑就一条——只要涉及精确数值,就别用原生浮点。把这条刻在脑子里,能避开八成以上的相关问题。

6. 浮点数还能怎么用:理解边界才能用好它

浮点数不是设计缺陷,它是工程上的权衡。用 64 位表示一个实数范围从 1e-308 到 1e308 的数,还要兼顾精度和性能,能做到现在这样已经很了不起了。科学计算、图形渲染、机器学习,这些领域大量依赖浮点数,它们对绝对精度不敏感,对范围和速度敏感,浮点数正好合适。

真正的问题在于用错场景。把浮点数用在金额、计数、需要精确比较的地方,就是拿螺丝刀当锤子使。理解它的边界,知道什么时候该用、什么时候该换,才是正确的态度。

如果你想把这块知识再往深挖,可以看看 IEEE 754 标准的完整文档,里面还有单精度、半精度、特殊值(NaN、Infinity)的处理规则。也可以自己写个小工具,把任意十进制小数转成 64 位二进制表示,亲手验证一遍 0.1 的存储结构,比看十篇文章都管用。

我个人在实际项目里的体会是,浮点数相关的 bug 往往不是技术难题,而是认知盲区。一旦你把二进制表示这条链路理顺了,再遇到类似问题,第一反应就会是“这里是不是精度问题”,排查效率能提升一大截。最后分享一个小技巧:调试浮点数问题时,别只看十进制打印结果,用Number.prototype.toString(2)或者 Python 的float.hex()看看底层二进制,很多疑惑当场就解开了。

相关新闻

AI智能体循环工程-第14章第6节-商业变现地图-产品化一把内部循环工具做成SaaS的路径

AI智能体循环工程-第14章第6节-商业变现地图-产品化一把内部循环工具做成SaaS的路径

第6节 产品化一&#xff1a;把内部循环工具做成SaaS的路径 一句话总结&#xff1a;从自用到SaaS五步——抽象垂直场景→多租户改造→计费&#xff08;座位/用量&#xff09;→合规安全→冷启动&#xff1b;借鉴Cursor&#xff08;$2B ARR&#xff09;与Devin的产品形态选择&…

2026/10/20 4:33:43 阅读更多 →
MySQL主从复制从原理到实战:binlog、GTID与高可用配置全解析

MySQL主从复制从原理到实战:binlog、GTID与高可用配置全解析

MySQL用了这么多年&#xff0c;真正让我意识到主从配置不是"加分项"而是"必选项"的&#xff0c;是一次线上事故——某天凌晨一个同事连错环境&#xff0c;一条UPDATE没带WHERE条件直接把用户表全量更新了。当时数据库只有一个实例&#xff0c;备份恢复花了…

2026/10/20 4:33:43 阅读更多 →
知识工作插件系统:模块化认知增强工具设计与实践

知识工作插件系统:模块化认知增强工具设计与实践

1. 项目概述&#xff1a;这不是插件&#xff0c;而是一套知识工作者的“思维外挂”系统“knowledge-work-plugins”这个标题乍看像某个开源仓库的命名&#xff0c;但拆开来看——knowledge work&#xff08;知识工作&#xff09;是现代职场最核心的生产力形态&#xff0c;plugi…

2026/10/20 4:33:43 阅读更多 →

最新新闻

视觉模型重塑时间序列分析:从离散Token到连续视觉的范式转换

视觉模型重塑时间序列分析:从离散Token到连续视觉的范式转换

1. 从离散Token到连续视觉&#xff1a;时间序列分析的新思路拆解时间序列分析这个领域&#xff0c;做的人多&#xff0c;但真正让人眼前一亮的突破少。传统方法从统计模型一路走到深度学习&#xff0c;Transformer架构进来之后&#xff0c;大家发现一个尴尬的事实&#xff1a;文…

2026/10/20 5:21:04 阅读更多 →
向AI提交创作需求:关键信息清单助你生成优质博客

向AI提交创作需求:关键信息清单助你生成优质博客

抱歉&#xff0c;我还没有收到您的项目标题和相关描述。麻烦您将以下信息发给我&#xff0c;我立刻开始创作&#xff1a;项目标题: [在这里填写标题] 项目正文: [零散描述也可以] 关键词: [关键词1, 关键词2, ...] 摘要描述: [一句话简介]收到后我会直接输出一篇完整的、可直接…

2026/10/20 5:21:04 阅读更多 →
PyTorch nn.DataParallel原理与实战:多卡训练的底层基石

PyTorch nn.DataParallel原理与实战:多卡训练的底层基石

1. 为什么今天还要深挖nn.DataParallel&#xff1f;它真过时了吗&#xff1f;在 PyTorch 生态里&#xff0c;提到多卡训练&#xff0c;很多人第一反应是DistributedDataParallel&#xff08;简称 DDP&#xff09;&#xff0c;社区文档、新教程、论文复现代码几乎清一色推荐它。…

2026/10/20 5:21:04 阅读更多 →
OpenCode接入Qwen模型实战:从选型配置到避坑指南

OpenCode接入Qwen模型实战:从选型配置到避坑指南

最近在折腾终端里的 AI 编程 Agent 工具 OpenCode&#xff0c;有一件事绕不开&#xff1a;模型配置。OpenCode 这类工具默认的模型接入方式对国内开发者不算友好&#xff0c;网络、计费、可用性都有门槛。好在这类工具大多支持自定义模型接入&#xff0c;而这几年国产开源模型里…

2026/10/20 5:21:04 阅读更多 →
榜单第一不等于实战能打:从Argon看大模型代码能力评价误区

榜单第一不等于实战能打:从Argon看大模型代码能力评价误区

开篇想聊个最近在圈子里传得挺开的事&#xff1a;某头部厂商放出了新的旗舰模型Argon&#xff0c;官方口径是“榜单18项第一”&#xff0c;从通用问答到复杂推理再到多模态理解&#xff0c;几乎把所有权威评测的榜首都揽了一遍。可等开发者们真把它拖到真实的代码仓库里跑任务&…

2026/10/20 5:21:04 阅读更多 →
智能支持员实战:从意图识别到多轮诊断的AI排障系统搭建

智能支持员实战:从意图识别到多轮诊断的AI排障系统搭建

做了这么多年技术支持&#xff0c;我对一件事特别有感触&#xff1a;真正占时间的不是那些疑难杂症&#xff0c;而是每天反复出现的“老三样”——服务起不来、配置不生效、报错信息看不懂。团队决定做“智能支持员”这个项目的时候&#xff0c;我的第一反应不是“又要上机器人…

2026/10/20 5:20:04 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →