谷歌:关于倒数乘法的琼斯
我们从小学就知道或应该知道,除以 n 等于乘以 1/n。我们还学习了如何使用小数位。和其他操作,所以乘以 1.234 与乘以 1234 然后除以 1000 或不知道你的结果是 1000 大。就像用便士而不是美元来思考一样,12.34 美元是 1234 便士。6 小时是 360 分钟,以此类推。
与小学相比,二进制的长除法是微不足道的。对于您移动的每个数字,除数适合下拉分子的时间可能正好为零或正好一次。基本上对于 1/6,你最终会得到 0.001010101010...二进制。
所以如果我想要 1234/6,我可以做 1234*0x2AAA = 0xCDA774。整数/定点答案是 205 这是 0xCD 所以有意义 0x2AAA 是 (1/6) 65536 所以 (X ((1/6)*65536))/65536 = X/6 或 (X*0x2AAA)>> 16 约为 X/6。
现在四舍五入呢?1234/6 实际上是 205 和 2/3,所以如果你想四舍五入怎么办。舍入意味着你在截止后取数字,如果它等于或高于你舍入的一半,对吗?那么 10101010 截止后的数字是 1,1/2 等于或高于一半,那么为什么不使用 0x2AAB 呢?
我们也知道 6 = 2*3。这两个数字很容易通过换档得到,所以你可以做 (N/3)/2 或 (N/2)/3。1/3 是 0.01010101... 二进制,其中 1/6 是 0.001010101...
所以这一切都应该导致一个粗略的想法,你可以如何乘以除以一个粗略的想法,他们乘以的 0xAB 可能来自哪里。但其他初等数学身份也可能在其中。
请注意,您不必在计算器上进行手动二进制除法,0x10000/6 = 0x2AAA。X/6 = (X*0X10000)/(6*0X10000) = (X/0X10000) (0X10000/6) = (X (0X10000/6))/0X10000。然后你只需要在尝试使用这个固定点时考虑精度/舍入。有时 16 位是不够的,你需要 24 或 32 或者谁知道......取决于除数。