art*_*101 4 c c++ bit-manipulation bit-shift bitwise-operators
可以说我有一个由4个32位整数组成的数组,用于存储128位数字
如何在此128位数字上左右移动?
谢谢!
与uint128
?如果可以的话,请使用x86 SSE指令,该指令正是为此而设计的。(然后,当您对值进行位移位时,就可以进行其他128位操作了……)
SSE2移位平均需要大约4条指令,并且只有一个分支(case语句)。移位超过32位也没有问题。完整的代码使用gcc内在函数而不是原始汇编器,位于sseutil.c
(github:“ SSE2的不寻常用法”)中–粘贴在这里比有意义的要大一些。
使用SSE2的许多人面临的障碍是,轮班操作数需要立即(恒定)的轮班计数。您可以使用一些C预处理器来解决问题(wordpress:C预处理器技巧)。之后,您将获得以下操作序列:
LeftShift(uint128 x, int n) = _mm_slli_epi64(_mm_slli_si128(x, n/8), n%8)
Run Code Online (Sandbox Code Playgroud)
当n = 65..71,73..79,…121..127 ...用两个指令进行整个移位时。
void shiftl128 (
unsigned int& a,
unsigned int& b,
unsigned int& c,
unsigned int& d,
size_t k)
{
assert (k <= 128);
if (k >= 32) // shifting a 32-bit integer by more than 31 bits is "undefined"
{
a=b;
b=c;
c=d;
d=0;
shiftl128(a,b,c,d,k-32);
}
else
{
a = (a << k) | (b >> (32-k));
b = (b << k) | (c >> (32-k));
c = (c << k) | (d >> (32-k));
d = (d << k);
}
}
void shiftr128 (
unsigned int& a,
unsigned int& b,
unsigned int& c,
unsigned int& d,
size_t k)
{
assert (k <= 128);
if (k >= 32) // shifting a 32-bit integer by more than 31 bits is "undefined"
{
d=c;
c=b;
b=a;
a=0;
shiftr128(a,b,c,d,k-32);
}
else
{
d = (c << (32-k)) | (d >> k); \
c = (b << (32-k)) | (c >> k); \
b = (a << (32-k)) | (b >> k); \
a = (a >> k);
}
}
Run Code Online (Sandbox Code Playgroud)