蝶式算法扩展-----16位按位转换

来源:互联网 发布:js点击按钮旋转图片 编辑:程序博客网 时间:2024/06/05 17:47

对蝶式算法的理解,将其扩展到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语言的移位操作,就能快速的解决此类问题。

原创粉丝点击