C++实现定点算术时移位操作的意义及相关代码疑问
首先纠正你一个关键错误:左移(<<)是将数字乘以2x,右移(`>>`)是除以2x,你搞反了,这是理解定点数的基础。
定点数的核心逻辑
定点数是用整数模拟带小数数值的方案,核心是约定一个固定的缩放因子——这里的scale=16,意味着缩放因子是2^16=65536。我们约定:
存储的整数值 = 实际数值 × 2^16
这样一来,实际数值的整数部分会占据存储整数的高位,小数部分对应低位的二进制位,以此实现用整数存储带小数的数。
逐函数解析移位的作用
DoubleToFixed
把浮点数转成定点数,本质就是按约定乘以缩放因子2^16。1 << scale是计算2^16的高效方式(移位运算比乘法指令更快),转成double后和输入浮点数相乘,得到的整数就是定点数的存储值。比如0.5 * 65536 = 32768,存储的32768在定点数体系里就代表0.5。FixedToDouble
是上面的逆操作:把存储的定点数整数除以缩放因子2^16,还原回原始的浮点数。比如32768 / 65536 = 0.5。IntToFixed(代码有笔误,应为return num << scale;)
把整数转成定点数,必须遵循同样的缩放规则。整数的实际数值就是它本身,所以要乘以2^16,左移16位就是最直接的实现。比如整数5,左移16位后是5 * 65536 = 327680——如果不做移位,直接存5的话,在定点数体系里会被解析成5/65536≈0.00004577,完全不是我们要的整数5,移位就是为了把整数放到定点数的「整数位区域」,符合统一的格式约定。
为什么整数转定点数需要移位?
因为定点数有统一的格式规则,所有数值(不管是整数还是小数)都要按「实际值×2^16」的规则存储。整数也必须遵守这个规则,才能和其他定点数正确运算、转换。移位是高效实现「乘以2的幂次」的方式,比直接用乘法更高效。
内容的提问来源于stack exchange,提问作者th3plus

