在数字 c# 中插入 1 位

Insert 1 bit in number c#

我在插入数字时遇到问题。我有一个位置可以插入这 1 位。例如,如果我有一个数字 186(以位表示:1011 1010)并且我有一个位置 4。它看起来是 1 0111 1010。我的第二个问题几乎与首先,但操作是在给定位置删除 1 位。如果我有位置 5,比特数将看起来是 101 1010。谢谢

保持冷静并学习如何

您可以使用 System.Collections.BitArray 完成此任务,它允许您将数字转换为位数组,然后操作该数字的各个位,然后再将其转换回来。以下是如何在某个 position:

处将 bit 插入 number
    public static byte insertIntoPosition(byte number, int position, bool bit)
    {
        // converting the number to BitArray
        BitArray a = new BitArray (new byte[]{number});

        // shifting the bits to the left of the position
        for (int j = a.Count - 1; j > position; j--) {
            a.Set (j, a.Get (j - 1));
        }

        // setting the position bit
        a.Set (position, bit);

        // converting BitArray to byte again
        byte[] array = new byte[1];
        a.CopyTo(array, 0);
        return array[0];
    }

从某个位置移除一点也很容易用这种方法完成。

我需要为我的 Z80.NET project 做完全相同的事情,这就是我解决问题的方法:

public static class NumberUtils
{
    public static byte WithBit(this byte number, int bitPosition, bool value)
    {
        if(bitPosition < 0 || bitPosition > 7)
            throw new InvalidOperationException("bit position must be between 0 and 7");

        if(value) 
            return (byte)(number | (1 << bitPosition));
        else 
            return (byte)(number & ~(1 << bitPosition));
    }
}

单元测试:

[Test]
public void SetBit_works_for_middle_bit()
{
    byte bit4reset = 0xFF;
    Assert.AreEqual(0xEF, bit4reset.WithBit(4, false));

    byte bit4set = 0x00;
    Assert.AreEqual(0x10, bit4set.WithBit(4, true));
}

下面的代码将插入一个位,而不会像使用 for 循环转换为位数组那样效率低下(将 O(1) 操作转换为 O(N) 操作)。

public static int InsertBit(int input, int pos, bool state) {
  //Split the input into two parts, one shifted and one not
  int bottom = input;
  int top = (input << 1);
  //insert a '0' or '1' before the shifted part
  if (state) top |= (1 << pos);
  else       top &= (~(1 << pos));
  //keep the top bits of top
  top &= (-1 << pos);
  //keep the bottom bits of bottom
  bottom &= ~(-1 << pos);
  //combine the two parts.
  return (bottom | top);
end;

请注意,这是 https://www.topbug.net/blog/2014/11/16/how-to-insert-1-bit-into-an-integer/
的翻译 所以不是我自己的代码。

去除一点更容易:

public static int RemoveBit(int input, int pos) {
  //Split the input into two parts, one shifted and one not
  int bottom = input;
  int top = (input >> 1);
  //keep the top bits of x
  top &= (-1 << pos);
  //keep the bottom bits of y
  bottom &= ~(-1 << pos);
  //combine the two parts.
  return (bottom | top);
end;

请注意,删除位将保留 input 的符号。如果 input 是负数,那么它会将 1 插入最高有效位。如果您不希望这样,则必须输入 unsigned int.