我确信之前已经问过,但是我需要在可变长度大小的字节数组上实现一个移位运算符。我看了一下,但我没有找到任何标准的方法。我提出了一个有效的实现,但我不确定它的效率如何。有没有人知道改变阵列的标准方法,或者至少对如何提高我的实现性能有任何建议;
char* baLeftShift(const char* array, size_t size, signed int displacement,char* result)
{
memcpy(result,array,size);
short shiftBuffer = 0;
char carryFlag = 0;
char* byte;
if(displacement > 0)
{
for(;displacement--;)
{
for(byte=&(result[size - 1]);((unsigned int)(byte))>=((unsigned int)(result));byte--)
{
shiftBuffer = *byte;
shiftBuffer <<= 1;
*byte = ((carryFlag) | ((char)(shiftBuffer)));
carryFlag = ((char*)(&shiftBuffer))[1];
}
}
}
else
{
unsigned int offset = ((unsigned int)(result)) + size;
displacement = -displacement;
for(;displacement--;)
{
for(byte=(char*)result;((unsigned int)(byte)) < offset;byte++)
{
shiftBuffer = *byte;
shiftBuffer <<= 7;
*byte = ((carryFlag) | ((char*)(&shiftBuffer))[1]);
carryFlag = ((char)(shiftBuffer));
}
}
}
return result;
}
答案 0 :(得分:1)
如果我可以添加@dwelch所说的内容,你可以试试这个。
只需将字节移动到最终位置即可。然后,如果每个字节仍然需要左移3位到下一个更高的字节,那么剩下的是移位计数,例如3。 (这在您的脑海中假设字节按从右到左的升序排列。)
然后将每个字节向左旋转3.查找表可能比单独执行实际旋转更快。然后,在每个字节中,要移位的3位现在位于字节的右端。
现在制作一个M
掩码(1<<3)-1
,这只是打开的低位3位。
现在,按顺序,从高位字节到低位字节,执行以下操作:
c[i] ^= M & (c[i] ^ c[i-1])
这会将掩码c[i]
下的位c[i-1]
复制到M
。
对于最后一个字节,只需使用0代替c[i-1]
。
对于正确的转变,同样的想法。
答案 1 :(得分:0)
我的第一个建议是消除位移周围的for循环。您应该能够在没有for(;displacement--;)
循环的情况下进行必要的转换。对于幅度大于7的位移,事情变得有点棘手,因为你的内部循环边界将改变,你的源偏移不再是1.即你的输入缓冲区偏移变为magnitude / 8
,你的移位变为magnitude % 8
。
答案 2 :(得分:0)
它确实看起来效率低下,也许这就是内森所指的。
假设一个char是8位,这个代码正在运行,有两件事要做,首先移动整个字节,例如,如果你的输入数组是0x00,0x00,0x12,0x34,你向左移8位然后你得到0x00 0x12 0x34 0x00,没有理由一次一个地循环8次。所以首先通过(位移&gt;&gt;&gt; 3)位置移动数组中的整个字符,然后填充用零创建的空洞(ra =(displacement&gt;&gt;&gt;&gt;&gt;&gt; 3); ra&gt; 3)] = array [ra ]。为(RA - =(位移&GT;&→3); RA&GT;(7-(位移及7)))。一个好的编译器将预先计算(位移&gt;&gt;&gt; 3),位移&amp; 7,7-(位移&amp; 7),一个好的处理器将有足够的寄存器来保存所有这些值。你可以通过为每个项目制作单独的变量来帮助编译器,但是根据编译器以及你如何使用它,它可能会使它变得更糟。
虽然底线是代码的时间。执行一千个1位移位然后一千个2位移位等等时间整个事情,然后尝试不同的算法并以相同的方式计时,看看优化是否有所作为,使其变得更好或更糟。如果您提前知道此代码将仅用于单个或少于8位的移位,则相应地调整时序测试。
使用进位标志意味着您知道许多处理器具有专门用于链接无限长移位的指令,使用标准寄存器长度(一次单个位)基本上通过进位旋转。哪种C语言不直接支持。对于链接单位移位,您可以考虑使用汇编程序,并且可能优于C代码。至少单个位移位比C代码可以做得快。如果要移位的位数(位移&amp; 7)可能小于4,则移动字节的混合使用汇编器使用C循环。再次,时序测试将告诉您优化的位置。