不使用除法计算A/3
推导出的公式:
因为 1/3 = 1/4 + 1/4^2 + 1/4^3 + 1/4^4 ... = (1/4)(1 - (1/4)^n)/(1 - 1/4);//1
所以 A/3 = A/4 + A/16 + A/64... //2
换成乘法: A/3 = (A*4^(16-1) + A*4^(16 - 2) + A*4^(16 - 3) +... + A*4^0)/4^16; //3
也就是: A/3 = (A*2^32 / 4 + A*2^32 / 4^2 + ... + A*2^32 / 4^16 )/ 2^32; //4
在公式2中,如果 A = 3;那么 A/4 = 0;(因为是整数的除法,结果为整数)之后的也是0;显然这是不合理的。为了保证精度。所以应该换成公式3,确保计算精度。另外, 这样还
不行。因为由公式1知:
1/3 = (1/4)(1 - (1/4)^n)/(1 - 1/4) = (1/3)(1 - (1/4)^n);
它总是比1/3要小的。如果A是3的倍数的话,那么结果肯定是错的。所以要添加修正,后来我发觉这个修正不应该是常数4,因为也不够精确:
在公式4中:
A/3 = (A*2^32 / 4 + A*2^32 / 4^2 + ... + A*2^32 / 4^16 )/ 2^32;
A/3 = A*2^32*(1/3)*(1 - (1/4)^16)/2^32 =(A*2^32/3 - A/3)/2^32
所以在除以2^32之前,减多了A/3;如果我们再给他加上一个A/3就可以解决问题了,但是,问题是根本不知道A/3等于多少,所以可以再加多一点,加一个A/2吧。
修正后:
A/3 =(A*2^32/3 - A/3 + A/2)/2^32 =(A*2^32/3 + A/6)/2^32 = A/3 + A/(6*2^32)
误差肯定是0了。因为A是32位的整形。
于是修正后的公式4:
A/3 = (A*2^32 / 4 + A*2^32 / 4^2 + ... + A*2^32 / 4^16 + A/2)/ 2^32
= (A*2^33/4 + A*2^33/4^2 + ... + A*2^33/4^16 + A)/2^33;
= A*(2^31 + 2^29 + 2^27 + ... + 2^2 + 1)/2^33;
= A*0xaaaaaaab /2^33;
= A*0xaaaaaaab>>33;