ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

乘数比较大时溢出处理(二)

乘数比较大时溢出处理(二) 目录1、数学原理拆解2、映射到你 ISP 直方图场景✅最关键溢出安全点3、分步数值实例演算使用拆分公式分步算4、纯 32‑bit 无 64 位依赖 C 标准实现5、边界极限测试total 取最大 32bit 值6、算法适用边界 注意事项ISP 工程坑点7、扩展适合 Verilog/RTL 硬件实现思路公式完整推导1、数学原理拆解任意整数 A 都可以写成带余除法形式其中→ 商整数除法结果→ 余数约束条件两边同乘 B两边除以 C向下取整C 语言无符号整数/就是向下截断取整2、映射到你 ISP 直方图场景算式对应参数直方图总像素uint32_t最大 4294967295百分比系数如 95范围一般 0~100固定除数代入公式✅最关键溢出安全点余数定义所以 r 的取值范围只能是0 ~ 99第二部分乘法r * ratioratio 最大 1009900 远远小于 32 位无符号数上限 (42 亿)第二部分乘法永远不会溢出 32bit第一部分ratio≤100 →该数值 ≤ 0xFFFFFFFF (4294967295) 第一部分乘法在32bit ratio范围为[0,100]场景下也不会溢出 32 位这就是为什么这个拆分算法不用任何 64‑bit (long long /uint64_t)纯 32 位运算就可以安全算出total*ratio/1003、分步数值实例演算举一个实际 ISP 例子total 2 100 520ratio 95C100直接计算真值使用拆分公式分步算✅结果完全相等无误差。再来一个带截断的例子不能整除 total 1000005ratio95 真值(1000005 * 95)/100 95000475 / 100 950004向下取整拆分计算q 1000005 / 100 10000r 1000005 % 100 5part1 1000095 950000part2 (595)/100 475/100 4result9500004950004 ✅结果完全一致。4、纯 32‑bit 无 64 位依赖 C 标准实现#include stdint.h /** * brief 32位安全计算 (A*B)/C 向下取整无64bit防止A*B乘法溢出 * param A 直方图总像素 total * param B 百分比 ratio (0~100) * param C 固定除数100 * retval (A*B)/C 的结果uint32 */ static uint32_t SafeMulDiv32(uint32_t A, uint32_t B, uint32_t C) { uint32_t q A / C; uint32_t r A % C; uint32_t part1 q * B; uint32_t part2 (r * B) / C; return part1 part2; } /* ISP直方图百分比阈值调用示例 */ uint32_t total GetHistogramTotalSum(); uint32_t ratio 95U; uint32_t cumu_th; cumu_th SafeMulDiv32(total, ratio, 100U);5、边界极限测试total 取最大 32bit 值total 0xFFFFFFFF (4294967295), ratio100 真值(4294967295 * 100)/100 4294967295拆分运算q 4294967295 / 100 42949672r 4294967295 % 100 95part1 42949672 * 100 4294967200part2 (95*100)/100 95result 4294967200 95 4294967295 ✅结果正确没有溢出。6、算法适用边界 注意事项ISP 工程坑点此拆分公式仅保证向下取整结果等价和 C 语言(A*B)/C截断行为 100% 一致该安全特性成立前提r*B 2^32 在场景 C100 → r100只要 B ≤ 42 949 672r*B 就永远不会溢出 ratio ≤ 100 完全满足条件如果你的 ratio 可以大于 4200 万这个算法就不再安全但百分比阈值场景 ratio 不会超过 100对比错误写法很多人偷懒// ❌错误精度大量丢失 thresh (total / 100U) * ratio;它丢掉了余数 r 带来的贡献也就是上面代码里的 part2会产生明显误差高分辨率大像素直方图下误差肉眼可见 而我们的 SafeMulDiv32 补上了 part2精度无损。7、扩展适合 Verilog/RTL 硬件实现思路如果你要给 ISP 硬件直方图模块写硬件逻辑无除法器可分时序实现第一步total除以 100 得到商 q余数 r第二步q × ratio → part1第三步r × ratio → temp第四步temp 除以 100 → part2第五步part1part2 输出阈值流水线可拆成 5 级全程通路位宽 32bit不需要 64 位乘法器。
返回列表