动态位移位/不移位

时间:2015-12-16 21:37:59

标签: c# math bit-manipulation

我想将多个块的值存储到整数中,就像我将ip转换为int一样。我的问题是我需要为n个块做这个,而不仅仅是4.我还需要指定每个块的最大值,对于所有块来说总是相同的。

因此,对于下面的示例,如果我想存储整个IP范围,我的BlockCount为4,而我的BlockSize为255,这是每个块的最大值。但是如果我降低我的BlockSize和/或BlockCount似乎无法工作。

这是我的第一次尝试,但它无法正常工作:

const int BlockSize = 100;
const int BlockCount = 3;

int shiftedValues = Shift(BlockSize, BlockCount);

for (int shiftedValue = 1; shiftedValue <= shiftedValues; shiftedValue++)
{
    for (int index = 0; index <= BlockCount; index++)
    {
        int blockValue = Unshift(index, shiftedValue);
    }        
}

private static int Shift(int blockSize, int blockCount)
{
    int result = 0;

    for (int i = 0; i < blockCount; i++)
    {
        result += ( blockSize << 8 * i );
    }

    return result;
}

private static int Unshift(int blockIndex, int shiftedValue)
{
    return ( shiftedValue >> ( blockIndex * 8 ) ) & 0xFF;   
}

1 个答案:

答案 0 :(得分:1)

上面的代码是我的解决方案,它是非常简单的代码,但随时可以要求澄清它。

class Program
{
    static void Main(string[] args)
    {
        int [] items = { 150 , 78 , 44 } ;
        int x = Program.Pack ( items , 150 ) ;
        int [] unpacked = Program.UnPack ( x , 150 , 3 ) ;
    }

    public static int Pack ( int[] blocks , int blockSize )
    {
        int size = (int)Math.Ceiling(Math.Log(blockSize, 2));
        int len = size * blocks.Length;

        if (len > 32)
            throw new Exception("Int Limit Exceeded");

        if ( blocks.Any ( x => x > blockSize ) )
            throw new Exception ( "There are some blocks that exceede the maximum block size" );

        List<bool> bools = new List<bool>();
        bools = bools.InitBoolArray(32);

        int i = 0 ;
        foreach (int block in blocks)
        {
            BitArray temp = block.ToBinary().Take(size);

            for ( int j = 0 ; j < size ; i++ , j++ )
                bools[i] = temp.Get(j);
        }

        return (new BitArray ( bools.ToArray() ) ).ToNumeral() ;
    }

    public static int[] UnPack ( int entry , int blockSize , int blockCount )
    {
        BitArray number = entry.ToBinary();
        int size = (int)Math.Ceiling(Math.Log(blockSize, 2));

        if (size > 32)
            throw new Exception("Int Limit Exceeded");

        List<int> result = new List<int>();

        for (int i = 0; i < blockCount; i++)
        {
            BitArray temp = number.Take(size);
            number = number.Shift (size );
            result.Add(temp.FitSize(32).ToNumeral());
        }

        return result.ToArray() ;
    }
}

使用扩展方法

public static class BinaryConverter
    {
        public static BitArray ToBinary(this int numeral)
        {
            return new BitArray(new[] { numeral });
        }

        public static int ToNumeral(this BitArray binary)
        {
            if (binary == null)
                throw new ArgumentNullException("binary");
            if (binary.Length > 32)
                throw new ArgumentException("must be at most 32 bits long");

            var result = new int[1];
            binary.CopyTo(result, 0);
            return result[0];
        }

        public static BitArray Take (this BitArray current, int length )
        {
            if (current.Length < length)
                throw new Exception("Invalid length parameter");

            List<bool> taken = new List<bool>();

            for (int i = 0; i < length; i++)
                    taken.Add(current.Get(i));

            return new BitArray(taken.ToArray());
        }

        public static BitArray Shift (this BitArray current, int length )
        {
            if (current.Length < length)
                throw new Exception("Invalid length parameter");

            List<bool> shifted = new List<bool>();

            for (int i = 0; i < current.Length - length; i++)
                shifted.Add(current.Get(length + i));

            return new BitArray(shifted.ToArray());
        }

        public static BitArray FitSize (this BitArray current, int size)
        {
            List<bool> bools = new List<bool>() ;
            bools = bools.InitBoolArray(size);

            for (int i = 0; i < current.Count; i++)
                    bools[i] = current.Get(i) ;

            return new BitArray(bools.ToArray());
        }

        public static List<bool> InitBoolArray(this List<bool> current, int size)
        {
            List<bool> bools = new List<bool> ();

            for (int i = 0; i < size; i++)
                bools.Add(false);

            return bools ;
        }
    }