對蝶式算法的理解,將其擴展到16爲半字數據的高低位轉換。
首先使用我們最常想到的移位算法,採用簡單的移位方式對數據的高低位進行轉換。該方式的優點是思路清晰,代碼相對簡單。對於新手來說會提高響應的編寫速度。
下面是對該思路的具體實現。採用C語言編寫
int16_t HighAndLowSwitchHEX(int16_t data)
{
uint8_t i = 0;
int16_t temp = 0x0000;
for(i = 0; i < 16; i++)
{
temp = ((data >> i) & 0x0001) | temp;
if(i < 16)
{
temp = temp << 1;
}
}
return temp;
}
對於上述代碼來說實現起來並不難,而且效率也比較高。但是還有更爲簡潔的解決方法,在嵌入式開發中遇到交換字節位的問題時常採用蝶式交換法和查表法來實現。查表法顧名思義是將一些值存到內存中,需要計算時查表即可,但是會佔用額外的存儲空間。嵌入式開發中,遇到較多的需要轉換的數據時,這種方式就會消耗大量的存儲空間。所以這裏對蝶式交換法進行介紹。
對於字節高低位交換的方法請參考該博客。
http://blog.csdn.net/syzcch/article/details/8149706
感謝博主的內容,爲我提供了新的思路
所謂的蝶式交換法,我引用了字節交換法的例子:
data=(data<<4)|(data>>4);
data=((data<<2)&0xcc)|((data>>2)&0x33);
data=((data<<1)&0xaa)|((data>>1)&0x55);
對於半字的蝶式交換法是這樣的:(如果大家有更好的例子歡迎討論)
data = (data << 8) | (data >> 8);
data = ((data << 4) & 0xF0FF) | ((data >> 4) & 0xFF0F);
data = ((data << 2) & 0xCCCC) | ((data >> 2) & 0x3333);
data = ((data << 1) & 0xAAAA) | ((data >>1 ) & 0x5555);
我們可以演算一下:
假設原始序列爲:1 0 0 1 0 1 1 0 0 1 0 1 1 0 1 1
目標序列爲: 1 1 0 1 1 0 1 0 0 1 1 0 1 0 0 1
data = (data << 8) | (data >> 8); //0 1 0 1 1 0 1 1 1 0 0 1 0 1 1 0
data = ((data << 4) & 0xF0FF) | ((data >> 4) & 0xFF0F); //1 0 1 1 0 1 0 1 0 1 1 0 1 0 0 1
data = ((data << 2) & 0xCCCC) | ((data >> 2) & 0x3333); //1 1 1 0 0 1 0 1 1 0 0 1 0 1 1 0
data = ((data << 1) & 0xAAAA) | ((data >>1 ) & 0x5555); //1 1 0 1 1 0 1 0 0 1 1 0 1 0 0 1
使用更爲抽象的例子,原始序列爲: A B C D E F G H I J K L M N O P
目標序列爲: P O N M L K J I H G F E D C B A
data = (data << 8) | (data >> 8); // I J K L M N O P A B C D E F G H
data = ((data << 4) & 0xF0FF) | ((data >> 4) & 0xFF0F); // M N O P I J K L E F G H A B C D
data = ((data << 2) & 0xCCCC) | ((data >> 2) & 0x3333); // O P M N K L I J G H E F C D A B
data = ((data << 1) & 0xAAAA) | ((data >>1 ) & 0x5555); // P O N M L K J I H G F E D C B A
由此完成了整個位的逆序轉換,完成了算法的拓展
下面是具體實現的代碼
/**
* @fn HighAndLowSwitchHEX(void)
* @brief 採用蝶式交換髮,對數據進行高低位變換,適用於16位數據
* @param data 要交換的數據
* @return 正確交換後的數據
*/
int16_t HighAndLowSwitchHEX(int16_t data)
{
data = (data << 8) | (data >> 8);
data = ((data << 4) & 0xF0FF) | ((data >> 4) & 0xFF0F);
data = ((data << 2) & 0xCCCC) | ((data >> 2) & 0x3333);
data = ((data << 1) & 0xAAAA) | ((data >>1 ) & 0x5555);
return data;
}
對於這種交換位的問題,在嵌入式開發中會經常遇到,應該熟練的利用好C語言的移位操作,就能快速的解決此類問題。