替换int的前面位

时间:2016-12-09 09:50:02

标签: c++ bit-manipulation

替换给定的int的第一个x位:

  1. 要替换的位数
  2. 一个新的比特序列
  3. e.g: 用5 位序列替换第一个 4 (1100 - > 10111)

    1100 0010 1001 - > 1 0111 0010 1001

    我知道如果使用std::bitset使用相同的长度,如何翻转这些位,但如果序列少于或多于第一个序列,我怎么能这样做呢?

    编辑:为了澄清,我需要用一定数量的位替换一定数量的最高有效位。我不需要算法来检查int是否太短而无法替换4位,我会处理它。给定一个int(转换为位),我只需要切断x位并连接y位

5 个答案:

答案 0 :(得分:1)

要么首先从位序列中的某个位置开始,该位置被认为是最高有效位(hsb),这意味着首先必须给出知道操作的位置,并且首先将改变,因为序列将包含更多或更少的位。
或者首先表示最低有效位(lsb),在这种情况下需要左/右移位来更改要替换的序列,因此它具有与新序列相同的大小。

00000100100011101001  
     ^hsb          ^lsb (which is actually first?)

顺便说一句:如果您希望序列增长而不指定构造时间,您可能需要查看boost.dynamic_bitset

答案 1 :(得分:0)

也许你可以......?

std::size_t x =3113; // which is 1100 0010 1001
std::size_t y =x%256; // remain of 2^8
x =y +23 *256; // add 1 0111 0000 0000

答案 2 :(得分:0)

我不记得要执行此操作所需的C ++函数,但我可以编写算法来实现所需的输出。



let,
int x = 0;
int n = 2; //number of bits to be replaced
int num = 11010; // 32 bit number to be manipulated with leading 0's
int unchanged_bits = bit seq length of num - n  
bit_seq = 101; so 11 will be replaced by 101 and 010 will be unchanged

do left shift x unchanged_bits times and add 1 each time // you will get 111 with leading 0's

now do logical & between num and 111 // you will get num with unchanged bits 010 with leading 0's

now left shift the given bit_seq 3 times// since length of 010 is 3 and you will get 101000

Now do logical OR between 101000 and 010 with leading 0's

Thus you will get desired output




答案 3 :(得分:0)

如果你想用一些新的比特序列n替换整数new_bits的前x位(在我的代码中使用first_set而不是x),你可以使用这个函数(假设函数int replace_first_bits(unsigned int n, int size_repl, int new_bits){ int first = first_set(n); if (first < 0){ //if no bit is set in n => n = 0 => return new_bits (CHANGE IF NECESSARY) return new_bits; } //replace bits `first` untill `(first+size-1)` => bits from `first+size` untill last bit stay the same int mask_size = (sizeof(unsigned int) << 3) - (first+size_repl); if (mask_size < 0){ // size_repl is greater than the length of n in binary notation // => replace much more than what is used => just replace everything (CHANGE IF NECESSARY) return new_bits; } int mask = (1 << mask_size) - 1; return (new_bits << mask_size) + (n & mask); } 返回设置的第一个位:

first_set

我已经像这样实施了int first_set(unsigned int i){ int count = sizeof(unsigned int) << 3; unsigned int n = i; while(n){ n = n >> 1; count--; } return count; }

unsigned int

您可能会注意到我使用了int而不是int。这是因为如果(签名)sizeof(unsigned int)为负数,则第一位为1。

我要补充的另一件事是我认为最左边的位为位0,最右边的位为位31(对于32位整数)。使用int我确定此代码适用于任何大小的1100 0010 1001

Here是代码的演示,其中包含您给出的示例:将10111(= 3113)的前4位替换为npm rebuild node-sass(= 23)。

希望它有所帮助。

PS:演示输出中的最后一行是帮助我计算位序列中位的索引。

答案 4 :(得分:0)

Result = [ Input-Pattern | Remains-after-MSBs-Trimmed-Out ]

您可以使用floor(log2(n))找到最高设置位(hsb),使用x找到输入数字numeric_limits<T>::digits中的位数。

size_t afterBitPos = floor(log2(x)) - numOfBitsToBeReplaced + 1;
size_t numberOfBits = (std::numeric_limits<unsigned>::digits - floor(log2(x)) - 1 + numOfBitsToBeReplaced );

//Clear "numberOfBits" MSBs
x <<= numberOfBits;
x >>= numberOfBits;

pattern <<= afterBitPos; //Position them in MSB positions.

x = x | pattern;

Live demo.