ETH官方钱包

前往
大廳
主題

補充說明多位元(bits)操作

Yang | 2022-10-25 16:54:54 | 巴幣 0 | 人氣 230

前一篇只能操作單位元,這裡補充說明多位元操作,原理是把不同位置的旗標先OR起來即可,另外也能練習C#的"|="與"params"語法

單元測試
Convert.ToString(10,2).PadLeft(8,'0')
"00001010"
Convert.ToString(0b_0000_1010,2).PadLeft(8,'0')
"00001010"

BitOperator.CheckBits(0b_0000_1010, 3, 2, 1)
false
BitOperator.CheckBits(0b_0000_1010, 3, 1)
true
BitOperator.CheckBits(0b_0000_1010, 5, 3, 1)
false
BitOperator.CheckBits(0b_0000_1010, 5)
false
BitOperator.CheckBits(0b_0000_1010, 3)
true

Convert.ToString(BitOperator.GetBits(0b_0000_1010,3,2,1),2).PadLeft(8,'0')
"00001010"
Convert.ToString(BitOperator.GetBits(0b_0000_1010,3,1),2).PadLeft(8,'0')
"00001010"
Convert.ToString(BitOperator.GetBits(0b_0000_1010,5,3),2).PadLeft(8,'0')
"00001000"
Convert.ToString(BitOperator.GetBits(0b_0000_1010,5),2).PadLeft(8,'0')
"00000000"
Convert.ToString(BitOperator.GetBits(0b_0000_1010,3),2).PadLeft(8,'0')
"00001000"

Convert.ToString(BitOperator.AddBits(0b_0000_1010,7),2).PadLeft(8,'0')
"10001010"
Convert.ToString(BitOperator.AddBits(0b_0000_1010,7,5),2).PadLeft(8,'0')
"10101010"
Convert.ToString(BitOperator.AddBits(0b_0000_1010,7,3),2).PadLeft(8,'0')
"10001010"
Convert.ToString(BitOperator.AddBits(0b_0000_1010,7,3,2,1),2).PadLeft(8,'0')
"10001110"

Convert.ToString(BitOperator.RemoveBits(0b_0000_1010,7),2).PadLeft(8,'0')
"00001010"
Convert.ToString(BitOperator.RemoveBits(0b_0000_1010,7,5),2).PadLeft(8,'0')
"00001010"
Convert.ToString(BitOperator.RemoveBits(0b_0000_1010,7,3),2).PadLeft(8,'0')
"00000010"
Convert.ToString(BitOperator.RemoveBits(0b_0000_1010,7,3,2,1),2).PadLeft(8,'0')
"00000000"

單元測試正常

public class BitOperator
{
    public static readonly uint[] BitValue = {
        (uint)Math.Pow(2, 0),
        (uint)Math.Pow(2, 1),
        (uint)Math.Pow(2, 2),
        (uint)Math.Pow(2, 3),
        (uint)Math.Pow(2, 4),
        (uint)Math.Pow(2, 5),
        (uint)Math.Pow(2, 6),
        (uint)Math.Pow(2, 7),
        (uint)Math.Pow(2, 8),
        (uint)Math.Pow(2, 9),
        (uint)Math.Pow(2, 10),
        (uint)Math.Pow(2, 11),
        (uint)Math.Pow(2, 12),
        (uint)Math.Pow(2, 13),
        (uint)Math.Pow(2, 14),
        (uint)Math.Pow(2, 15),
        (uint)Math.Pow(2, 16),
        (uint)Math.Pow(2, 17),
        (uint)Math.Pow(2, 18),
        (uint)Math.Pow(2, 19),
        (uint)Math.Pow(2, 20),
        (uint)Math.Pow(2, 21),
        (uint)Math.Pow(2, 22),
        (uint)Math.Pow(2, 23),
        (uint)Math.Pow(2, 24),
        (uint)Math.Pow(2, 25),
        (uint)Math.Pow(2, 26),
        (uint)Math.Pow(2, 27),
        (uint)Math.Pow(2, 28),
        (uint)Math.Pow(2, 29),
        (uint)Math.Pow(2, 30),
        (uint)Math.Pow(2, 31),
    };

    public static bool CheckBit(in byte value, in int position)
    {
        if (position < 0 || position >= sizeof(byte) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return (value & BitValue[position]) > 0;
    }

    public static bool CheckBits(in byte value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(byte) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return (value & bits) == bits;
    }

    public static byte GetBit(in byte value, in int position)
    {
        if (position < 0 || position >= sizeof(byte) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return (byte)(value & BitValue[position]);
    }

    public static byte GetBits(in byte value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(byte) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return (byte)(value & bits);
    }

    public static byte AddBit(in byte value, in int position)
    {
        if (position < 0 || position >= sizeof(byte) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return (byte)(value | BitValue[position]);
    }

    public static byte AddBits(in byte value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(byte) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return (byte)(value | bits);
    }

    public static byte RemoveBit(in byte value, in int position)
    {
        if (position < 0 || position >= sizeof(byte) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        //return CheckBit(value, position) ? (byte)(value - BitValue[position]) : value;
        return (byte)(value & ~BitValue[position]);
    }

    public static byte RemoveBits(in byte value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(byte) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return (byte)(value & ~bits);
    }

    public static bool CheckBit(in uint value, in int position)
    {
        if (position < 0 || position >= sizeof(uint) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return (value & BitValue[position]) > 0;
    }

    public static bool CheckBits(in uint value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(uint) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return (value & bits) == bits;
    }

    public static uint GetBit(in uint value, in int position)
    {
        if (position < 0 || position >= sizeof(uint) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return value & BitValue[position];
    }

    public static uint GetBits(in uint value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(uint) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return value & bits;
    }

    public static uint AddBit(in uint value, in int position)
    {
        if (position < 0 || position >= sizeof(uint) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        return value | BitValue[position];
    }

    public static uint AddBits(in uint value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(uint) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return value | bits;
    }

    public static uint RemoveBit(in uint value, in int position)
    {
        if (position < 0 || position >= sizeof(uint) * 8)
        {
            throw new IndexOutOfRangeException($"{nameof(position)}={position}");
        }

        //return CheckBit(value, position) ? value - BitValue[position] : value;
        return value & ~BitValue[position];
    }

    public static uint RemoveBits(in uint value, params int[] positions)
    {
        if (positions == null || positions.Length <= 0)
        {
            throw new ArgumentException($"{nameof(positions)} == null || {nameof(positions)}.Length <= 0");
        }

        uint bits = 0;

        foreach (int position in positions)
        {
            if (position < 0 || position >= sizeof(uint) * 8)
            {
                throw new IndexOutOfRangeException($"{nameof(position)}={position}");
            }

            bits |= BitValue[position];
        }

        return value & ~bits;
    }
}
送禮物贊助創作者 !
0
留言

創作回應

更多創作