位移指令實現乘法、除法計算

前言

大家都知道51單片機是有乘法、除法指令的,不管是用C語言還是彙編語言,都是可以直接計算乘法、除法的,我以爲+,-,*,/ 這些算術運算是單片機的標配,而我公司使用的應廣單片機居然沒有乘法、除法指令,應廣單片機使用的是mini-C語言,和C語言有點像,可以在C代碼中穿插彙編指令。但mini-C不支持for循環,也不支持函數傳參,所以一下代碼都沒有傳參,也沒有for循環。

乘法

思路0

我們都知道左移1位(<<1)相當於乘2,左移2位(<<2)相當於乘4,但想乘3、乘5、乘6、乘7怎麼辦?
在已知要乘多少時,我們可以考慮這種方法

int a=13;
b=a<<1;//b=a*2
b=(a<<1)+a;//b=a*3
b=a<<2;//b=a*4
b=(a<<2)+a;//b=a*5
b=(a<<2)+a+a;//b=a*6
b=(a<<3)-a;//b=a*7
b=a<<3;//b=a*8
//.....

思路1

前面的方法顯然不是我想找的,也不是你想找的,我需要一個實現乘法的功能:a×b,a是變量,b也是變量。
再想想,例如做9×4時,我們是如何計算除法的?相信大家首先想到的是乘法口訣“四九三十六” 那是中國人太聰明瞭有乘法口訣,若是老外計算,可能就是“nine plus nine equals eighteen, eighteen plus nine equals twenty seven …”,乘法的本質就是把n個數相加,所以寫程序的時候做循環相加即可以實現乘法計算。

byte ma;//第一個因式,這裏byte等價於unsigned char
byte mb;//第二個因式
word mc;//計算結果,這裏word等價於unsigned int
void mult(void)
{
	mc=0;
	while(mb)
	{
		mc+=ma;
		mb--;
	}
}

很好理解,mb是幾,mc就循環加幾次ma,但這個方法在比較耗時,例如2×100時,2+2+2+2+…+2,這裏有100次加法運算。

思路2

小學乘法的豎式計算也同樣適用於二進制
在這裏插入圖片描述

因爲二進制只有0或1,ma×1=ma,ma×0=0;程序中只需要:
①判斷被乘數mb的最低位,若爲1則mc累加ma,爲0則不累加(或累加0)
②讓ma左移1位,mb右移1位
③再次回到①,直到mb變爲0,運算結束

word ma;//第一個因式,計算結果也存放在ma
byte mb;//第二個因式
void mult(void)
{
	word t=0;
	while(mb)
	{
		if(mb.0)//if(mb&0x01)
		{
			t+=ma;
		}
		ma<<=1;
		mb>>=1;
	}
	ma=t;
}

對於上面是程序,大大減少了計算時間,最壞情況ma*11111111B需要循環8次,一共8次累加、8次左移、8次右移。
這個程序也可以做一點優化,先比較ma、mb的大小,用大的數乘以小的數。
這樣可以讓0000 0001B×1111 1111B這樣的乘法更快計算完成。

if(mb>ma)
{
	t=mb;	mb=ma;	ma=t;
}
t=0;

除法

思路0

通過右移指令實現÷2、÷4、÷8等,但對於除以其他數卻不行了。

思路1

和乘法一樣,除法也可以理解爲減法。
例如:16個蘋果分給5個孩子

  1. 每個孩子拿1個,還剩16-5=11個
  2. 每個孩子再拿1個,還剩11-5=6個
  3. 每個孩子再拿1個,還剩6-5=1個
    這時不夠每個孩子拿1個了,所以餘數是1,每個人都有3個,所以商是3。
byte ma;//被除數、商
byte mb;//除數、餘數
void div(void)
{
	byte n=0;
	while(ma>mb)
	{
		ma-=mb;
		n++;
	}
	mb=ma;
	ma=n;
}

這個方法對於被除數大、除數小的情況會耗時比較久。
大家可以考慮一下除數爲0會發生什麼,該怎麼解決。

思路2

同樣使用除法豎式來幫助理解

在這裏插入圖片描述
被除數高位需要對齊除數低位,再比較被除數與除數的大小決定要不要商1,但程序似乎不好寫。再來看另一張圖片
在這裏插入圖片描述

先將除數左移字長-1bit,就可以低位對齊並且可以相減了。
對照圖片中的思路應該很好理解下面的程序。

byte ma;//被除數、商
word mb;//除數、餘數
void div(void)
{
	word t=0;
	byte i=8;
	mb<<=7;
	while(i--)
	{
		t<<=1;
		if(ma>=mb)
		{
			ma-=mb;
			temp|=0x01;
		}
		mb>>=1;
	}
	mb=ma;//餘數
	ma=t;//商
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章