以0x67 / 3来举例 说明:

除数3前面有6个0, 减数从 3 * 2^6 次方 0xC0 开始, 循环去减, 每循环一次
减数/2, 够减则说明被除数中包含了减数/(原始减数3)个原始减数, 商+1, 然后在后面的每一次循环
时移位, 实现了商加上相应倍数的减数.

除数循环7(6+1)次也就到了除数自身, 减最后一次, 循环结束
算法巧妙的利用了移位减法, 以最少的循环次数实现了求商除法运算

被除数               减数                    结果
67[0110 0111] C0[1100 0000] 00[0000 0000]
67[0110 0111] 60[0110 0000] 01[0000 0001]
//够减, +1, 60是3的0x20 倍, 后面不断的左移, 保证了现在的+1最后成为0x20
07[0000 0111] 30[0011 0000] 02[0000 0010]
07[0000 0111] 18[0001 1000] 04[0000 0100]
07[0000 0111] 0C[0000 1100] 08[0000 1000]
07[0000 0111] 06[0000 0110] 11[0001 0001]
01[0000 0001] 03[0000 0011] 22[0010 0010]

对应的C代码实现如下: 对应的C代码实现如下:

BYTE sub_div2(BYTE dividend, BYTE divisor)
{
	BYTE result = 0;
	int zeroNum = 0;
	BYTE C = 0;
	if (dividend && divisor)
	{
		zeroNum = 0;
		C = 0;
		BYTE bCarry = 0;
		do
		{	//计算除数中从高到低, 第一个Bit1的位置
			zeroNum++;
			if (!(divisor & 0x80))
				divisor <<= 1;
		} while (!(divisor & 0x80));

		zeroNum++;
		do
		{
			if (dividend < divisor)
			{	//被除数没有除数大, 不够减
				C = 1;
			}
			else
			{
				C = 0;
				dividend -= divisor;
			}

			C = !C;
			//取反后C为1, 说明够减
			bCarry = result & 0x80;
			result <<= 1; result |= C; zeroNum--; divisor >>= 1;
		} while (zeroNum != 0);
	}

	return result;
}

转载请注明转自: 听风 , 本文固定链接: 单片机多字节移位除法实现方案