Day 51:浮点数精度与舍入误差(Floating-Point Precision and Rounding Errors)

implicit conversion increases floating-point precision: ‘float‘ to ‘double‘ [-Werror,-Wdouble-promot frameworks/native/libs/gui/SurfaceComposerClient.cpp:345:57: error: implicit conversion increases floating-point precision: 'float' to 'double' [-Werror,-Wdouble-promotion] ALOGE("client setMatrix, %.2f, %.2f, %.2f, %.2f,", (dsdx), (dtdx), (dtdy), (... 阅读详情

上一讲我们深入分析了隐式类型转换(Implicit Conversion)在C语言中的复杂陷阱,包括符号扩展、精度丢失和类型混用导致的隐晦Bug。
今天进入
Day 51:浮点数精度与舍入误差(Floating-Point Precision and Rounding Errors)
,这是C语言数值计算中极易被低估、但对工程和科学应用影响极大的问题。


1. 主题原理与细节逐步讲解

1.1 浮点数的存储与精度

  • C语言中的主要浮点类型有float(32位)、double(64位)、long double(平台相关,通常80位或128位)。
  • 浮点数遵循IEEE 754标准存储,由三部分组成:符号位、指数部分、尾数(有效数字/mantissa)。
  • 浮点数在存储时只能近似表示大多数实数,很多小数无法被精确表达,只能取最近的可用“格点”。

1.2 精度损失的本质

  • 有限位宽导致无法精确存储绝大多数实数,如0.1在二进制下为无限循环小数,存储时会被截断。
  • 连续的加减、乘除等运算都会累积舍入误差。
  • 在不同平台、不同编译器、不同优化级别下,浮点数运算结果可能略有不同。

1.3 常见误差类型

  • 舍入误差(Rounding Error):数值被舍入到最近的可表示值。
  • 累积误差(Accumulation Error):大量运算后舍入误差累积,结果越来越偏离真实值。
  • 下溢和上溢(Underflow/Overflow):超出浮点数可表达范围,变为0或无穷大。
  • 精度损失(Loss of Significance):大数减小数后结果精度大幅降低。

2. 典型陷阱/缺陷说明及成因剖析

2.1 相等判断陷阱

  • 浮点数直接用==比较,几乎永远不该做,因为微小误差可能导致本应相等的数被判为不等。

2.2 精度累积与级联损失

  • 连续加减操作,尤其是大数减小数,易导致有效位丢失。

2.3 隐式类型转换带来的精度劣化

  • 将double赋值给float,或将浮点数赋给整型,丢失精度。

2.4 格式化输出误导

  • %f、%.2f等格式化输出会四舍五入,仅显示部分小数位,掩盖了存储中的实际误差。

3. 规避方法与最佳设计实践

3.1 间接相等判断(误差容忍)

  • 比较两个浮点数应判断它们的差是否小于某个容忍范围(epsilion)。
#define EPS 1e-6
if (fabs(a - b) < EPS) {
    // 认为a和b“足够接近”
}

3.2 保持统一类型和精度

  • 运算中避免float和double混用,优先使用double或更高精度类型。
  • 避免将高精度数据赋值到低精度变量。

3.3 避免大数减小数

  • 哪怕算法上等价,也要避免大数减小数的操作,可以通过重排或数学变换优化。

3.4 累加算法优化(如Kahan补偿)

  • 使用Kahan求和算法等数值分析技术减小累积误差。

3.5 明确输出精度

  • 输出浮点结果时,明确指定小数位数,并提醒用户实际精度有限。

4. 典型错误代码与优化后正确代码对比

错误示例1:直接比较相等

float a = 0.1f * 10;
if (a == 1.0f) {
    printf("Equal\n");
} else {
    printf("Not Equal\n");
}
// 输出 "Not Equal"

分析:0.1f无法精确表示,a实际为0.99999994…

正确做法:
#include <math.h>
#define EPS 1e-6
float a = 0.1f * 10;
if (fabsf(a - 1.0f) < EPS) {
    printf("Equal\n");
} else {
    printf("Not Equal\n");
}

错误示例2:精度级联损失

double a = 1e20;
double b = 1.0;
double c = (a + b) - a; // 期望c==1.0,实际c==0.0
printf("%.1f\n", c); // 输出0.0

原因:a+b的结果因有效数字受限,b被吞没。

正确做法:
  • 优先重排运算顺序,或避免大数小数混合。

错误示例3:float与double混用

float x = 1.123456789f;
double y = x; // y精度只和x一致,已丢失高位

分析:float到double不会“补回”精度。

正确做法:
  • 源数据应始终用高精度存储。

5. 必要底层原理补充

  • IEEE 754标准规定了浮点数的存储格式和舍入规则。
  • 浮点数的有效数字与指数范围有限,不能指望浮点数精确表达所有实数。
  • 浮点数运算的非结合性((a + b) + c ≠ a + (b + c)),累计误差无法避免。

6. 图示:浮点数存储与舍入示意

在这里插入图片描述


7. 总结与实际建议

  • 浮点数运算绝非精确运算,应时刻考虑精度和舍入误差的影响。
  • 禁止直接用==比较浮点数,应采用误差容忍法。
  • 保持运算类型和精度一致,避免大数减小数和累积误差。
  • 关注算法重排和数值稳定性,必要时采用补偿求和等技术。

结论:浮点数精度和舍入误差是C语言数值运算中不可回避的底层规律。只有理解其原理并设计健壮的容错机制,才能编写可靠的科学与工程程序。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

【人工智能评测】基于Java+Vue的知识问答数据集管理系统:多维度自动判分与评分一致性分析平台设计 项目介绍 基于java+vue的直播电商商家准入审核与违规样本库平台设计与实现(含模型描述及部分示 内容概要:本文介绍了一个基于Java和Vue的知识问答评测数据集管理与判分一致性系统的设计与实现。系统旨在解决AI问答模型评测过程中存在的数据分散、人工评分标准不一、评分结果难以追溯等问题。通过构建统一的数据集管理体系,支持问题、参考答案、模型答案、评分维度等结构化存储,并引入多维度自动判分机制,结合关键词覆盖率、余弦相似度等算法实现客观指标量化。系统还提供多人评分一致性分析功能,利用平均绝对差、Kappa系数等统计方法评估评分一致性,标记争议样本并触发复核流程。整体架构采用Spring Boot + Vue前后端分离模式,集成MySQL、Redis和消息队列,保障高效稳定运行,并支持评测任务调度、权限控制与审计日志,形成从数据管理到模型优化的闭环。; 适合人群:具备Java与Vue开发基础,从事人工智能评测系统、知识库平台或教育测评工具研发的工程师及技术人员,尤其适合工作1-3年、希望深入理解评测系统设计逻辑的研发人员。; 使用场景及目标:① 构建标准化的知识问答评测平台,实现大规模数据的统一管理与批量处理;② 设计多维度自动评分模型,提升评测客观性与效率;③ 分析多人评分一致性,减少主观偏差,支撑模型迭代优化决策;④ 实现从评测任务创建、自动打分、人工复核到统计分析的全流程闭环管理。; 阅读建议:此资源不仅包含系统架构与核心代码示例,还涵盖评分算法实现与数据生成逻辑,建议结合Maven依赖配置与代码实践,搭建原型系统进行调试与扩展,重点关注评分权重校验、一致性计算与多源数据导入等关键环节的设计思路与实现细节。 立即下载

相关推荐

Delphi 13.2控件之无人机智能巡检系统平台介绍(1).zip

Delphi 13.2控件之无人机智能巡检系统平台介绍(1).zip

消除警告

#pragmaclang diagnostic push#pragmaclang diagnostic ignored"-Wdeprecated-declarations"这里写出现警告的代码#pragmaclang diagnostic pop源网址WarningMessage-WCFString-literalinput conversion stopped due to an input b

sinat_32972877的博客 1万+

YOLO26算法纺织品面料纹理识别目标检测+训练好的模型+405张数据集+pyqt可视化界面.zip

附训练好的 YOLO 权重与 PyQt 可视化检测界面,页面底部含可视化效果预览,毕设/课设开箱即用。 【数据集概况】 · 检测类别(中文):[腈纶(acrylic), 棉(cotton), 雪纺(crepe), 牛仔(denim), 皮革(leather), 亚麻(linen), 尼龙(nylon), 丝绸(silk)] · 训练集:254 张 · 验证集:100 张 · 测试集:51 张 · 总计:405 张 该数据集聚焦于高精度纺织品面料材质识别场景,专为服装制造、纺织质检与智能零售等环节中对布料种类的快速准确判别需求而构建,具有明确的工业应用导向与实用价值。... 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 71 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.8112** mAP50-95 | 0.8063 Precision | 0.8162 Recall | 0.7480 train/box_loss | 0.1215 train/cls_loss | 0.5972 val/box_loss | 0.1691 val/cls_loss | 1.7964 【训练过程分析】 从一开始,训练过程的曲线图就给我留下了深刻的印象。开始的几轮,loss 值快速下降,模型仿佛找到了自己的节奏,准确率的提升明显。在最初的20轮里,训练曲线像是在说,一切都在按部就班地进行,模型似乎在享受着这个阶段的平滑下降,每一轮都向着最佳值一点点逼近。然而,到了第25轮之后,loss 下降的速度突然... 使用场景:毕业设计、课程设计、深度学习入门、工业场景落地验证。

IOS 警告 汇总

Semantic Warnings Warning Message -WCFString-literal input conversion stopped due to an input byte that does not belong to the input codeset UTF-8 -WNSObject-attribute

孙启超 5万+

高校技术转移办公室如何实现技术成果的智能推荐与精准路演?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

国央企创新负责人如何快速识别具有产业化潜力的科技成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

iOS消除对应的警告!

在iOS开发过程中, 我们可能会碰到一些系统方法弃用, weak、循环引用、不能执行之类的警告。 有代码洁癖的孩子们很想消除他们, 今天就让我们来一次Fuck 警告!!首先学会基本的语句 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" 这里写出现警告的代码#prag

贤_龍的博客 2354

弱电网下虚拟同步发电机正负序阻抗建模仿真复现【扫频发+阻抗建模】

内容概要:本文聚焦于弱电网环境下虚拟同步发电机(VSG)的正负序阻抗建模仿真,系统阐述基于扫频法的频域阻抗建模方法,旨在分析VSG并网系统的稳定性问题。通过Simulink仿真平台完整复现正负序阻抗提取过程,采用小信号扰动技术获取系统频率响应,并结合奈奎斯特稳定性判据评估系统的稳定裕度。文档深入解析了正负序激励的施加方式、动态响应采集与阻抗曲线拟合等关键技术环节,同时涵盖光伏并网逆变器的序阻抗建模与稳定性判断方法,突出阻抗建模在弱电网交互稳定性分析中的核心作用。配套提供详细的仿真模型、参考文献及说明文档,有助于读者深入理解建模原理并实现结果复现。; 适合人群:适用于电气工程、电力电子与电力系统及其自动化等相关专业的研究生、科研人员,以及从事新能源并网逆变器、虚拟同步机技术研发的工程师;要求具备MATLAB/Simulink仿真能力,并熟悉交流系统对称分量法、频域分析及并网控制基本理论。; 使用场景及目标:① 掌握弱电网条件下VSG及光伏逆变器的正负序阻抗建模流程;② 学习运用扫频法进行精确的频域系统辨识与阻抗特性提取;③ 基于阻抗模型开展稳定性分析,支撑高水平科研论文撰写或实际工程项目中的并网兼容性验证。; 阅读建议:建议结合所提供的Simulink模型与参考文献同步研习,重点掌握扫频信号参数设置、正负序解耦机制、频率响应数据处理及奈奎斯特判据的应用细节,注意区分不同控制策略对阻抗特性的影响,确保准确完成建模与稳定性评估全过程。

也谈浮点精度问题:找回丢失的精度

要点<br />在java float double精度为什么会丢失?浅谈java的浮点数精度问题 中描述了java中float精度丢失的问题:即便是整数也可能发生精度丢失。顺着其思路,我们简要复习一下关于floating point的精度问题IEEE754arithmetic formats<br />Binary floating-point numbers are stored in a sign-magnitude form where the most significant bit i

FireCoder的专栏 2600

政府科技管理者如何高效配置区域科技资源实现精准对接?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

ArduPilot代码解析之四 — 姿态和位置控制

ArduPilot采用级联控制架构实现飞行器的姿态和位置管理。该系统通过位置→速度→加速度→姿态→角速率→电机指令的逐级转换,将高级指令转化为底层执行信号。位置控制采用三维独立控制,水平轴与垂直轴分别处理;姿态控制通过角度误差→角速率→电机输出的两层级联实现。系统支持多种输入模式,并内置运动学整形功能确保轨迹平滑。不同飞行器类型(多旋翼、直升机、潜艇等)有专门的调参方案,通过调整PID参数、加速度限制等实现最优控制性能。该架构兼顾控制精度与飞行稳定性,适用于各类自主飞行场景。

rainercool的专栏 817

Objective-C 警告相关说明

原文地址:http://nshipster.com/clang-diagnostics/

2万+

Librepilot _64位window10环境下的搭建及一些坑的解决办法

  刚入IT行业的小菜鸟,在window上折腾了四天的librepilot地面控制站的搭建,想着这么辛苦不能白费了,看网上相关资料少得可怜,唯一一个详细教程还是在32位环境下,一大堆坑,所以把自己的经验写下来,供大家一起参考。 参考的原文是:https://www.cnblogs.com/jasonchan1202/p/7809937.html的博客,但是执行下来才发现这个博客对64位系统极其不...

weixin_41426339的博客 2722

破除匪夷所思bugs,从修正编译警告开始

交付软件给客户却是很多问题,一些问题解决就可以了。但有些问题却是一时出现,一时不出现,十分令人恼火,程序猿是超人也难以应付。本文以编译警告为引入点述说在开发过程中的匪夷所思的问题。引以为鉴,重视警告的影响。

Qt君 6158

Android 面试题 Handler篇

1.Handler的实现原理。

ViewHandKownHealth的博客 939

JavaScript实现斗地主(附完整源码)

JavaScript实现斗地主(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1492

【一生一芯 / PA】AM 核心文件逐行解析(上):从 start.S 到 gpu.c

本文逐行解析AM的10个核心文件,构建最小可运行环境:start.S启动并调用_trm_init;trm.c注册事件处理、初始化CTE并执行main;nemu.h定义硬件地址与停机指令;riscv.h提供MMIO读写接口;am.h定义五层抽象接口;amdev.h宏生成设备寄存器结构;ioe.c实现设备分发表;timer.c、input.c、gpu.c分别处理定时器、键盘、显卡。各文件依序协作,形成完整的RISC-V模拟器基础框架。

nskksms的博客 91

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+
上一篇: 一款隔离的USB转4-20mA、±10V模拟量输出模块的设计
下一篇: Day 52:浮点数的比较陷阱(Traps of Floating-Point Comparison)
boringhex.top
博客等级 码龄17年 1946粉丝 360原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值