有网友在论坛中给出了2个非常好的实现方法,原讨论的URL是:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3703075&bbs_page_no=1&bbs_id=3020
重点摘录如下:
第一种方法的思路:
【19楼】 zjzhou
使用乘法很方便的,简单的写个方法
long <= t1.b3-t1.b0 // t1低四字节
long = (long & 0x01010101) * 0x01020408; // 结果低四位在最高字节中
再处理高四位后合并低四位,其余的也类似处理
第一种方法的一个具体实现:
【41楼】 coldfish
unsigned char t1[8]={0x24,0x21,0xf0,0x7f,0x80,0x37,0xff,0x1f};//test data
unsigned char t2[8];
union
{
unsigned long l[2];
unsigned char c[8];
} Tmp;
unsigned char i;
long Ll,Lh;
for (i=0;i<8;i++)
Tmp.c=t1;
i=8;
while(i--)
{
Ll=(Tmp.l[0]&0x01010101)*0x01020408;
Lh=(Tmp.l[1]&0x01010101)*0x01020408;
t2=unsigned char(((Lh&0x0F000000)>>20)|((Ll&0x0F000000)>>24));
Tmp.l[0]>>=1;Tmp.l[1]>>=1;
}
【45楼】 minux 啊啊? 给出了更简洁的第二种算法。
示例程序如下:
#include <stdio.h>
void transpose8(unsigned char i[8], unsigned char o[8]) {
unsigned long x, y, t;
x = (i[0] << 24) | (i[1] << 16) | (i[2] << 8) | i[3];
y = (i[4] << 24) | (i[5] << 16) | (i[6] << 8) | i[7];
t = (x & 0xf0f0f0f0) | ((y >> 4) & 0x0f0f0f0f);
y = ((x << 4) & 0xf0f0f0f0) | (y & 0x0f0f0f0f);
x = t;
t = (x ^ (x >> 14)) & 0x0000cccc;
x = x ^ t ^ (t << 14);
t = (y ^ (y >> 14)) & 0x0000cccc;
y = y ^ t ^ (t << 14);
t = (x ^ (x >> 7)) & 0x00aa00aa;
x = x ^ t ^ (t << 7);
t = (y ^ (y >> 7)) & 0x00aa00aa;
y = y ^ t ^ (t << 7);
o[7] = x >> 24; o[6] = x >> 16; o[5] = x >> 8; o[4] = x;
o[3] = y >> 24; o[2] = y >> 16; o[1] = y >> 8; o[0] = y;
}
int main(void) {
int i;
unsigned char t1[8]={0x24,0x21,0xf0,0x7f,0x80,0x37,0xff,0x1f};
unsigned char t2[8];
transpose8(t1, t2);
for (i = 0; i < 8; i++)
printf("0x%x ", t2);
return EOF == putchar('\n');
}
运行结果:0x57 0x17 0x97 0x13 0x37 0xf6 0x32 0x2a
没专门对ARM-v7M优化,不过我觉得速度应该能接受了,应该比直接进行位操作分别操作每个位的方法快一倍。
文章评论(0条评论)
登录后参与讨论