Language agnostic 使用逐位操作连接位。这可能吗?

Language agnostic 使用逐位操作连接位。这可能吗?,language-agnostic,programming-languages,bit-manipulation,Language Agnostic,Programming Languages,Bit Manipulation,我想问的是,是否可以将所有位合并到两个不同的数字中 伪代码示例: bytes=array(0x04, 0x3F); //place bitwise black magic here print 0x043F; 另一个例子: bytes=array(0xFF, 0xFFFF); //place bitwise black magic here print 0xFFFFFF; bytes=array(0x34F3, 0x54FD); //place bitwise black magi

我想问的是,是否可以将所有位合并到两个不同的数字中

伪代码示例:

bytes=array(0x04, 0x3F);

//place bitwise black magic here

print 0x043F;
另一个例子:

bytes=array(0xFF, 0xFFFF);

//place bitwise black magic here

print 0xFFFFFF;
bytes=array(0x34F3, 0x54FD);

//place bitwise black magic here

print 0x34F354FD;
还有一个例子:

bytes=array(0xFF, 0xFFFF);

//place bitwise black magic here

print 0xFFFFFF;
bytes=array(0x34F3, 0x54FD);

//place bitwise black magic here

print 0x34F354FD;

我想将此限制为仅限位运算符(
>
,如果我正确理解您的问题,
这应该是php中的答案:

    $temp = $your_first_value << strlen(dechex($the_length_of_the_second_value_in_hex))
    $result = $temp | $your_second_value
    print dechex($result)

$temp=$your_first_value根据您的计算机的端号,您可能需要颠倒字节[0]和以下字节的顺序:

uint8_t字节[2]={0x04,0x3f};

uint16_t result=(bytes[0]这个问题完全取决于能否确定整数中最左边的1的位置。一种方法是“向右涂抹位”,然后对1进行计数:

向右涂抹:

int smearright(int x) {
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x;
}
很简单,这里只有按位运算符。但是,计算位需要某种加法:

int popcnt(int x) {
    x = add(x & 0x55555555, (x >> 1) & 0x55555555);
    x = add(x & 0x33333333, (x >> 2) & 0x33333333);
    x = add(x & 0x0f0f0f0f, (x >> 4) & 0x0f0f0f0f);
    x = add(x & 0x00ff00ff, (x >> 8) & 0x00ff00ff);
    x = add(x & 0xffff, (x >> 16) & 0xffff);
    return x;
}
但是没关系,
add
可以实现为

int add(int x, int y) {
    int p = x ^ y;
    int g = x & y;
    g |= p & (g << 1);
    p &= p << 1;
    g |= p & (g << 2);
    p &= p << 2;
    g |= p & (g << 4);
    p &= p << 4;    
    g |= p & (g << 8);
    p &= p << 8;
    g |= p & (g << 16);
    return x ^ y ^ (g << 1);
}
再也没有
popcnt

用位运算符实现乘法是没有帮助的,那更糟糕,我甚至不确定你能用列出的运算符实现乘法(除非正确的移位是算术移位,但这仍然是一件可怕的事情,涉及32个加法,每个加法都是函数本身)

在这个答案中没有“诡计”,例如使用隐式测试与零相等的条件(“隐藏”
!=0
if
?:
while
等),并且控制流实际上是完全线性的(函数调用只是为了防止重复代码,一切都可以内联)


这里有一个替代方法。不要使用
popcnt
,而是执行一个奇怪的变量移位:

int shift_by_mask(int x, int mask) {
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    return x;
}

使用加法(`+')的运算符。我只指定了且只指定了按位运算符。我进行了编辑以突出显示该部分并列出了要使用的运算符。但您确实提供了一个非常好的解决方案!实际上,
$temp=$your\u first\u值您的答案现在与uliwitness的答案完全相同,这有同样的问题。如果
$your\u second\u值de>限制在0和255之间。假设只有1个字节。我要问的是任意数字(引用:
我要问的是,是否可以将所有位合并到2个不同的
数字中)。我又添加了两个我假装的示例,以澄清我的预期。因此,唯一的问题是解决第二个值的长度(十六进制),然后一切都应该正常吗?您的解决方案假设这些是字节。我要求的是两个数(引用:
我想问的是,是否有可能将所有位加入两个不同的
数字
)。不同之处在于它不仅限于字节。如果第二个数字介于0和255之间,则您的解决方案非常有效。我添加了两个以上的示例,以澄清我的预期。如果它们不是单字节,则情况相同。只需根据数字的位数调整数据类型和位移位量。但是MBER可以是负的、正的、32位的、64位的、0,-1(我对这个问题的处理方式有所不同)。您的解决方案需要事先知道您将使用哪种类型。是的,这是一种方法,但它只适用于
bytes[1]
介于0(
0x00
)和255(
0xff
)之间的情况。另一个数字如256(
0x1ff
,内存编号)将返回虚假结果。您的问题没有包含任何这些要求,因此我猜这不是您想要的。我所做的只是为您的原始问题提供解决方案。:-)@哈罗德忘了那个问题。我会添加它。@harold还添加了
~
,自从Begging之后ben就应该在那里了。这是一个语言不可知的问题,你似乎只给出了一个c语言的答案。Javascript和PHP不适用于这个问题。PHP甚至没有无符号数字!@IsmaelMiguel我这样做是为了在审查结果证明是不必要的。顺便说一句,它不应该是C,我在写它的时候就想到了C(当然,逻辑右移并不是C#所独有的)。这里是将代码重写为1个函数。它满足了所有的要求并起作用!您可以在这里测试:(它使用2个
do{}while
循环,这还不错)。
join = (left * (smearright(right) + 1)) | right;
int shift_by_mask(int x, int mask) {
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    mask >>= 1;
    x <<= mask & 1;
    return x;
}
join = shift_by_mask(left, smearright(right)) | right;