当前位置: 首页 > news >正文

整数溢出陷阱:用除法安全比较乘积

整数溢出陷阱:用除法安全比较乘积

在金融、电商、游戏等涉及大数值的业务中,经常出现类似判断:

if(balance>=unitPrice*quantity){// 余额足够支付}

unitPrice * quantity超出整型上限时,计算结果发生环绕,条件失效。尤其在 32 位环境下(int32_t上限约 21 亿),9 亿单价乘以 1 万数量,乘积 9 万亿远超上限,直接溢出为负数或小正数,导致错误放行或误拒。

本文给出一种零成本、完全等价的防御写法。


1. 溢出问题演示

假设使用int64_t存储金额(单位为分),手上余额balance = 9000 0000 0000(900亿分),需判断能否支付单价unitPrice = 9 0000 0000(9亿分)的 1 万件商品。

乘法表达式:

9 0000 0000 * 10000 = 9 0000 0000 0000 (9万亿)

int64_t最大值约 922 亿亿,看似不会溢出,但若使用int32_tuint32_t则会直接溢出。即便使用 64 位,若单价和数量进一步放大,依然会溢出。核心问题是:无法预知乘积是否越界


2. 解决方案:除法比较

将原条件balance >= unitPrice * quantity等价转换为:

balance / quantity >= unitPrice

前提:quantity > 0。这是业务上的自然约束(数量不能为 0 或负)。

转换后,除法运算的上限是balance,不会超出整型范围,彻底规避乘法溢出。


3. 等价性证明

balance = q * quantity + r,其中0 ≤ r < quantity,则balance / quantity = q

原条件:

balance >= unitPrice * quantity ⇔ q * quantity + r >= unitPrice * quantity ⇔ q + r/quantity >= unitPrice

由于r/quantity < 1,且unitPrice为整数,因此q + r/quantity >= unitPrice等价于q >= unitPrice。即:

balance / quantity >= unitPrice

整除截断不会造成误判,比较结果严格等价


4. 决策流程

在实际编码中,可以先用乘法安全阈值判断是否走除法分支,以获得最佳性能:

判断 balance >= unitPrice * quantity

quantity == 0?

处理 quantity 为 0 的边界

unitPrice > MAX / quantity?

直接比较 balance >= unitPrice * quantity

除法比较 balance / quantity >= unitPrice

返回结果

其中MAX为当前整型的最大值。若unitPrice > MAX / quantity,乘积必溢出,走除法路径;否则乘法安全。


5. 注意事项

  • quantity 必须为正整数。如果业务中可能出现 0 或负值,提前做参数校验。
  • 整除不会影响正确性。比较运算不关心余数,截断后的商已经足以判定。
  • 无需引入高精度或浮点库。原地使用原有整型,指令开销与乘法几乎无差别。
  • 可用于无符号整数。所有讨论同样适用于uint32_t/uint64_t,且无需担心符号位。

6. 总结

遇到形如A >= B * C且乘积可能溢出时,直接改写为A / C >= BC > 0)。这是一种简洁、可移植、无性能损失的防御技术,无需扩展整数宽度,就能彻底消除隐性溢出 bug。

在数值范围不可预知的接口中,养成这种写法习惯,能从源头避免难以复现的边界错误。

http://www.rkmt.cn/news/1525220.html

相关文章:

  • NSK LPFC 1616-3 高刚性零背隙滚珠丝杠技术解析
  • Google 爬虫工作原理,及用Python实现完整的Google爬虫
  • Wayback Machine浏览器扩展:让消失的网页永远触手可及的数字时光机
  • 你的会议麦克风真的‘智能’吗?拆解ANS噪声抑制在腾讯会议、Zoom里的实际表现
  • 基于MATLAB的静止无功补偿系统设计3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 终极LRC歌词批量下载指南:10分钟让离线音乐库焕发新生
  • 西湖区处理全套附件大牌包,奢二网专业鉴定爱马仕Kelly、铂金包 - 讯息早知道
  • 如何在3小时内搭建你自己的怀旧传奇服务器:OpenMir2终极指南
  • 从零开始打造你的AI角色:SillyTavern角色卡片完全指南
  • 2026青岛首饰回收行业实测:行情解析与避坑白皮书 - 逸程
  • AI 辅助的前端国际化文案本地化策略:从机械翻译到语境适配,多语言产品的智能交付
  • MPC8309 eLBC FCM硬件控制器驱动NAND Flash原理与实践
  • 广州天河区搬家工人闲置摆摊:盒饭从6元降到免费,同城搬家行业供需困局深度解析 - 从来都是英雄出少年
  • 线上三大和田玉品牌对比测评:优选肖氏珠宝 - 速递信息
  • 杭州临安区闲置名牌包包线下估价|奢二网全覆盖一线箱包,本地网点估价透明不压价 - 讯息早知道
  • Vue 3 Teleport 与异步组件深度实践:从 DOM 约束到逻辑自由,组件架构的灵活性跃迁
  • 2026济南宝格丽首饰回收指南:新手全流程实操手册 - 薛定谔的梨花猫
  • 2026降AI率平台实测:10款网站对比,论文质量提升秘籍 - 降AI小能手
  • 【信息科学与工程学】【通信工程】第二百零一篇 路由器设备中的学科知识01
  • OpenHands 新手实战:开源版 Devin 如何读取项目、修改代码、运行测试?
  • MPC8245 JTAG与监视点:硬件级调试的实战指南
  • 5分钟掌握网盘直链下载助手:8大平台高速下载的终极指南
  • 闲置翡翠回血避坑!青岛 6 家同城回收门店亲测甄选 - 讯息早知道
  • String的isEmpty与equals(““)的区别
  • 专业定制超级电容器公司推荐 - 品牌排行榜
  • 20公斤走物流还是快递?20公斤寄什么划算?物流还是快递,比价后选寄半折 - 快递物流资讯
  • 广州白云区搬家公司推荐 端午节工人连休3天不调休,高端别墅/写字楼搬迁完整避坑实操指南 - 从来都是英雄出少年
  • 3个方法彻底优化论坛浏览体验:NGA论坛增强脚本完全指南
  • 郑州装修公司推荐|2026郑州装修公司top10、本土靠谱装修怎么选,这8大雷区千万别踩 - 速递信息
  • 2026杭州二手名表回收实测TOP7门店榜单:专业仪器无损鉴表,正规连锁出表零套路 - 薛定谔的梨花猫