对128位数字进行按位移位操作

art*_*101 4 c c++ bit-manipulation bit-shift bitwise-operators

可以说我有一个由4个32位整数组成的数组,用于存储128位数字

如何在此128位数字上左右移动?

谢谢!

Mis*_*cha 5

uint128?如果可以的话,请使用x86 SSE指令,该指令正是为此而设计的。(然后,当您对值进行位移位时,就可以进行其他128位操作了……)

SSE2移位平均需要大约4条指令,并且只有一个分支(case语句)。移位超过32位也没有问题。完整的代码使用gcc内在函数而不是原始汇编器,位于sseutil.cgithub:“ 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 ...用两个指令进行整个移位时。


Rem*_*anu 4

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)