连续double范围到离散byte范围的双向无损映射实现问题
实现方案
核心逻辑说明
要满足convertToByte(convertToDouble(y)) == y的恒成立要求,本质是要让[100,200]区间的每个byte值都对应[10.0,20.0]区间内唯一的固定double映射点,正向转换时把输入double映射到离它最近的映射点对应的byte值即可。
首先计算离散值数量:[100,200]的byte共 200 - 100 + 1 = 101 个取值,对应把[10.0,20.0]的区间拆分为100个等距步长,每个步长长度为 (20.0 - 10.0) / (200 - 100) = 0.1。
转换函数实现
1. byte转double函数 convertToDouble
输入为[100,200]范围内的byte值,直接按照步长计算对应double值即可:
double convertToDouble(byte y) { // 输入范围校验为可选逻辑 if (y < 100 || y > 200) { throw new IllegalArgumentException("y must be in [100, 200]"); } return 10.0 + (y - 100) * 0.1; }
2. double转byte函数 convertToByte
输入为[10.0,20.0]范围内的double值,先缩放后四舍五入取整,再钳位到[100,200]区间避免边界精度误差:
byte convertToByte(double x) { // 输入范围校验为可选逻辑 if (x < 10.0 || x > 20.0) { throw new IllegalArgumentException("x must be in [10.0, 20.0]"); } int scaled = (int) Math.round((x - 10.0) * 10.0); // 钳位操作 scaled = Math.max(0, Math.min(100, scaled)); return (byte) (100 + scaled); }
正确性验证
对任意[100,200]的byte值y都可通过以下步骤验证恒成立:
- 调用
convertToDouble(y)得到值为10.0 + (y-100)*0.1 - 把该值传入
convertToByte,计算得( (10.0 + 0.1*(y-100)) - 10.0 ) *10 = y-100 - 四舍五入后结果仍为
y-100,加100就得到原始y,完全满足要求。
注意事项
- 若输入double超出[10.0,20.0]范围,可根据业务需求选择抛出异常或者直接钳位到边界值(100或200)
- 四舍五入逻辑保证了每个double值都会被映射到最近的byte对应点,不会出现跨点误差
内容的提问来源于stack exchange,提问作者zellidev0
相关产品推荐
相关产品推荐

