尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ISP图像处理中大数乘法溢出处理(三)

ISP图像处理中大数乘法溢出处理(三) 工具函数 132×32 乘法输出 64 位结果四分 16‑bit 拆分乘法纯 32 位运算原理拆分所有子项都是 16bit ×16bit结果最大 32bit不会溢出 32 位。代码实现#include stdint.h /* 高低双32bit字模拟64位无符号数 */ typedef struct { uint32_t hi; uint32_t lo; } U64Pair; /** * brief 两个uint32相加输出结果进位 */ static void AddU32(uint32_t a, uint32_t b, uint32_t *sum, uint32_t *carry) { *sum a b; *carry (*sum a) ? 1U : 0U; } /** * brief 64位无符号加法 z x y */ static U64Pair U64_Add(U64Pair x, U64Pair y) { U64Pair z; uint32_t sum0, c0, sum1, c1; AddU32(x.lo, y.lo, sum0, c0); AddU32(x.hi, y.hi, sum1, c1); AddU32(sum1, c0, z.hi, c1); z.lo sum0; return z; } /** * brief uint32 × uint32 →64位结果(U64Pair) * 16bit四分拆分乘法全程无任何64位原生类型 */ static U64Pair Mul32x32(uint32_t a, uint32_t b) { U64Pair res; uint32_t a0 a 0xFFFFU; uint32_t a1 a 16U; uint32_t b0 b 0xFFFFU; uint32_t b1 b 16U; uint32_t p00 a0 * b0; uint32_t p01 a0 * b1; uint32_t p10 a1 * b0; uint32_t p11 a1 * b1; uint32_t mid_sum, mid_carry; AddU32(p01, p10, mid_sum, mid_carry); /* ---低32位运算: lo p00 (mid_sum 16) --- */ uint32_t mid_shifted mid_sum 16U; uint32_t lo_carry; AddU32(p00, mid_shifted, res.lo, lo_carry); /* ---高32位分步累加携带进位杜绝溢出丢失 --- */ uint32_t h_sum, h_carry; // part A: mid_sum 16 h_sum mid_sum 16U; // part B: mid_carry 16 AddU32(h_sum, (mid_carry 16U), h_sum, h_carry); // part C: p11 AddU32(h_sum, p11, h_sum, h_carry); // part D: lo_carry AddU32(h_sum, lo_carry, res.hi, h_carry); /* h_carry 此时一定等于0因为32×32乘积最高64bit */ return res; }工具函数 264 位被除数 (U64Pair) ÷ 32 位除数 → 32 位商二进制移位‑减法长除法经典 shift‑subtract 长除法完全可以直接映射成 Verilog 流水线硬件无任何乘法、无 64 位变量。代码实现/** * brief 64位无符号被除数 ÷32位除数向下取整返回32bit商 * param num 被除数 {hi,lo} * param den 除数 den0den不能等于0 */ static uint32_t Div64By32(U64Pair num, uint32_t den) { uint32_t quotient 0U; uint32_t rem_hi num.hi; uint32_t rem_lo num.lo; uint32_t carry; for(int32_t i 63; i 0; i--) { /* 余数整体左移1bit */ carry rem_lo 31U; rem_lo rem_lo 1U; rem_hi (rem_hi 1U) | carry; quotient quotient 1U; /* ✅修复后正确判断64bit余数 32bit除数 */ if((rem_hi ! 0U) || (rem_lo den)) { /* 执行余数 余数 - den */ if(rem_lo den) { rem_lo - den; } else { rem_lo (0xFFFFFFFFU - den) rem_lo 1U; rem_hi - 1U; } quotient | 1U; } } return quotient; } /** * brief SafeMulDiv_No64 floor(A*B/C) * 纯32位运算无uint64_t通用安全乘法永不溢出 * param A total 直方图总和 * param B ratio 百分比 * param C divisor 除数直方图场景填100U */ static uint32_t SafeMulDiv_No64(uint32_t A, uint32_t B, uint32_t C) { U64Pair product Mul32x32(A, B); return Div64By32(product, C); } /* 四舍五入扩展版本(直方图抗闪烁可选) */ static uint32_t SafeMulDiv_Round_No64(uint32_t A, uint32_t B, uint32_t C) { U64Pair product Mul32x32(A, B); U64Pair add; add.hi 0U; add.lo C / 2U; product U64_Add(product, add); return Div64By32(product, C); }
返回列表