如何正确将uint16_t整数在[0..4092]与[0..255]区间间缩放?
整数缩放:[0..4092] uint16_t 到 [0..255] 的均匀映射
首先明确核心需求:输入共4093个值(0到4092),输出256个值(0到255),需要每个输出对应15或16个输入值(因为4093 ÷ 256 ≈15.988),且避免浮点运算。
为什么原有公式不符合要求
- 公式
y = x * 255 / 4092:仅当x=4092时y=255,其余最大y为254,导致255仅对应1个输入,严重不均匀。 - 公式
y = (x * 255 + 2045) / 4092:255对应9个输入,仍未实现15/16的均匀分布。
正确的整数计算方法
要实现均匀映射,需基于输入总数和输出总数的比例来计算,正确公式为:
y = (x * 256) / 4093;
原理说明
- 输入总个数为
4093(4092 - 0 + 1),输出总个数为256(255 - 0 + 1)。 - 用
x * 256将输入值映射到0~4092*256的范围,再除以输入总数4093,通过整数除法自动实现区间划分:- 前253个输出值(y=0到y=252),每个对应16个输入值(例如y=0对应x=0~15,共16个)。
- 最后3个输出值(y=253、254、255),每个对应15个输入值(例如y=255对应x=4078~4092,共15个)。
- 总输入数验证:25316 + 315 = 4048 + 45 = 4093,完全匹配输入范围的总个数。
无溢出保证
由于x是uint16_t(最大值4092),x * 256的结果为4092*256=1047552,该值小于uint32_t的最大值(4294967295),因此在计算时需将x强制转换为32位整数避免溢出,例如在C语言中:
uint8_t scale_value(uint16_t x) { return (uint8_t)((uint32_t)x * 256 / 4093); }
内容的提问来源于stack exchange,提问作者Soonts
相关产品推荐
相关产品推荐

