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;