Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 128位数字上的按位移位操作_C++_C_Bit Manipulation_Bitwise Operators_Bit Shift - Fatal编程技术网

C++ 128位数字上的按位移位操作

C++ 128位数字上的按位移位操作,c++,c,bit-manipulation,bitwise-operators,bit-shift,C++,C,Bit Manipulation,Bitwise Operators,Bit Shift,假设我有一个由4个32位整数组成的数组,用来存储128位的数字 如何在这个128位数字上执行左移位和右移位 谢谢 为什么不使用位集而不是128位数字?使用位集,您可以调整它的大小。此外,您还可以对其执行许多操作 您可以在此处找到有关这些的更多信息: 既然您提到将128位值存储在4个整数的数组中,您可以执行以下操作: void left_shift(unsigned int* array) { for (int i=3; i >= 0; i--) { a

假设我有一个由4个32位整数组成的数组,用来存储128位的数字

如何在这个128位数字上执行左移位和右移位


谢谢

为什么不使用位集而不是128位数字?使用位集,您可以调整它的大小。此外,您还可以对其执行许多操作

您可以在此处找到有关这些的更多信息:


既然您提到将128位值存储在4个整数的数组中,您可以执行以下操作:

void left_shift(unsigned int* array)
{   
    for (int i=3; i >= 0; i--)
    {
        array[i] = array[i] << 1;

        if (i > 0)
        {
            unsigned int top_bit = (array[i-1] >> 31) & 0x1;
            array[i] = array[i] | top_bit;
        }
    }
}

void right_shift(unsigned int* array)
{   
    for (int i=0; i < 4; i++)
    {
        array[i] = array[i] >> 1;

        if (i < 3)
        {
            unsigned int bottom_bit = (array[i+1] & 0x1) << 31;
            array[i] = array[i] | bottom_bit;
        }
    }
}
void左移位(无符号整数*数组)
{   
对于(int i=3;i>=0;i--)
{
数组[i]=数组[i]0)
{
无符号整数顶部位=(数组[i-1]>>31)&0x1;
数组[i]=数组[i]|顶位;
}
}
}
无效右移位(无符号整数*数组)
{   
对于(int i=0;i<4;i++)
{
数组[i]=数组[i]>>1;
如果(i<3)
{
无符号整数底部\u位=(数组[i+1]&0x1)
void shiftl128(
无符号整数&a,
无符号整数和整数,
无符号整数和整数,
未签名整数与整数,
尺寸(k)
{
assert(k=32)//将32位整数移位超过31位是“未定义的”
{
a=b;
b=c;
c=d;
d=0;
移位128(a、b、c、d、k-32);
}
其他的
{
a=(a>(32-k));
b=(b>(32-k));
c=(c>(32-k));
d=(dk)\
c=(b>k)\
b=(a>k)\
a=(a>>k);
}
}

首先,如果要按
n
位进行移位,并且
n
大于或等于32,则除以32并将整数移位。这应该很简单。现在剩下的移位计数将从0变为31。如果为零,请提前返回,就完成了


对于每个整数,您需要将剩余的
n
移位,然后将相邻整数移位相同的量,并将每个整数的有效位组合起来。

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

SSE2位移位平均需要4条指令,有一个分支(case语句)。移位超过32位也没有问题。执行此操作的完整代码是,使用gcc内部函数而不是原始汇编程序,位于
sseutil.c
()——它比粘贴在这里有点大

许多人在使用SSE2时遇到的障碍是移位运算需要立即(恒定)进行移位计数。您可以通过一些C预处理器旋转()来解决这一问题。之后,便有了如下的移位运算序列:

LeftShift(uint128 x, int n) = _mm_slli_epi64(_mm_slli_si128(x, n/8), n%8)
对于n=65..71,73..79,…121..127
…在两条指令中完成整个移位。

@C Johnson我同意可以使用位集,但我从更逻辑的角度来看它,并将这4个32位整数作为k>32的约束失败。你不认为函数比宏更好吗?@MArtin:你说得对,在这方面没有考虑过,或者移位超过32。@Remus Rusanu和MArtin:非常感谢!除了提到的移位大于32的问题外,宏版本还有一些常见的宏问题:使用的参数没有完全括起来,如果参数不是32位类型或有符号类型,宏可能会出现不希望出现的行为,宏不是“语句安全”的(它们应包装在
do/while(0)
或类似文件中)。此外,宏似乎执行shift操作,但名称表明存在旋转-如果我遇到使用宏的代码,我会感到困惑。任何考虑使用宏的人都应该注意解决问题。或者使用函数版本。@Remus Rusanu:此代码中仍然有一个bug。递归的条件应该是
if(k>=32)
。为什么不使用2
int64\t
?它会使事情比4
int32\t
简单得多。你应该显示相关代码,而不是在场外链接。我已经厌倦了你的宏实现,但可能需要展开它以使访问者更清楚。
LeftShift(uint128 x, int n) = _mm_slli_epi64(_mm_slli_si128(x, n/8), n%8)