动态位移位/ Unshifting [英] Dynamic Bit Shifting / Unshifting

查看:152
本文介绍了动态位移位/ Unshifting的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想块的多个值存储到以同样的方式整数,因为我可以将IP转换成int类型。我的问题是,我需要为n个块,不仅4.还我需要specifiy每个块,这是永诺为所有块相同的最大值。

做到这一点

所以,对于下面的例子中,如果我想存储整个IP范围我BlockCount是4,我的块大小为255,这是每个块的最大值。但似乎没有,如果我降低我的块大小和/或BlockCount工作。

这是我第一次尝试,但它不能正常工作:

  const int的块大小= 100;
const int的BlockCount = 3;INT shiftedValues​​ = Shift键(块大小,BlockCount);对(INT shiftedValue = 1; shiftedValue&下; = shiftedValues​​; shiftedValue ++)
{
    对于(INT指数= 0;&指数LT = BlockCount;指数++)
    {
        INT blockValue =不印字(索引,shiftedValue);
    }
}私有静态诠释移(INT块大小,诠释blockCount)
{
    INT结果为0;    的for(int i = 0; I< blockCount;我++)
    {
        结果+ =(块大小<< 8 * I);
    }    返回结果;
}私有静态诠释的unshift(INT blockIndex,诠释shiftedValue)
{
    返回(shiftedValue>>(blockIndex * 8))及0xFF的;
}


解决方案

上面的code是我的解决方案,这是pretty简单code,但随时提出澄清一下。

 类节目
{
    静态无效的主要(字串[] args)
    {
        INT [] =项目150 {78,44};
        INT X = Program.Pack(项目150);
        INT []解压= Program.UnPack(X,150,3);
    }    公共静态INT包(INT []块,块大小INT)
    {
        INT大小=(int)的Math.Ceiling(将Math.log(块大小,2));
        INT LEN =尺寸* blocks.Length;        如果(LEN> 32)
            抛出新的异常(内部超限);        如果(blocks.Any(X => X>的块大小))
            抛出新的异常(有一些块的exceede的最大块大小);        清单<布尔>布尔变量=新的List<布尔>();
        的bool = bools.InitBoolArray(32);        INT I = 0;
        的foreach(以块INT块)
        {
            BitArray TEMP = block.ToBinary()采取(大小)。            对于(INT J = 0; J<大小;我++,J ++)
                布尔变量[I] = temp.Get(J);
        }        返回(新BitArray(bools.ToArray())).ToNumeral();
    }    公共静态INT []解压(INT项,INT块大小,INT blockCount)
    {
        BitArray数= entry.ToBinary();
        INT大小=(int)的Math.Ceiling(将Math.log(块大小,2));        如果(大小> 32)
            抛出新的异常(内部超限);        清单< INT>结果=新的List< INT>();        的for(int i = 0; I< blockCount;我++)
        {
            BitArray TEMP = number.Take(大小);
            数= number.Shift(大小);
            result.Add(temp.F​​itSize(32).ToNumeral());
        }        返回result.ToArray();
    }
}

使用有扩展方法

 公共静态类BinaryConverter
    {
        公共静态BitArray ToBinary(此数字INT)
        {
            返回新BitArray(新[] {数字});
        }        公共静态INT ToNumeral(此BitArray二进制)
        {
            如果(二== NULL)
                抛出新的ArgumentNullException(二进制);
            如果(binary.Length> 32)
                抛出新的ArgumentException(必须至多32位长);            变种结果=新INT [1];
            binary.CopyTo(结果,0);
            返回结果[0];
        }        公共静态BitArray拿(这个BitArray目前,INT长度)
        {
            如果(current.Length<长度)
                抛出新的异常(无效的长度参数);            清单<布尔>采取=新名单<布尔>();            的for(int i = 0; I<长度;我+ +)
                    taken.Add(current.Get(I));            返回新BitArray(taken.ToArray());
        }        公共静态BitArray Shift键(此BitArray目前,INT长度)
        {
            如果(current.Length<长度)
                抛出新的异常(无效的长度参数);            清单<布尔>转移=新的List<布尔>();            的for(int i = 0; I< current.Length - 长度;我+ +)
                shifted.Add(current.Get(长+ I));            返回新BitArray(shifted.ToArray());
        }        公共静态BitArray FitSize(这BitArray目前,INT大小)
        {
            清单<布尔>布尔变量=新的List<布尔>();
            布尔变量= bools.InitBoolArray(大小);            的for(int i = 0; I< current.Count;我++)
                    的bool [I] = current.Get(ⅰ);            返回新BitArray(bools.ToArray());
        }        公共静态列表<布尔> InitBoolArray(名单<布尔>目前,INT大小)
        {
            清单<布尔>布尔变量=新的List<布尔> ();            的for(int i = 0; I<大小;我++)
                bools.Add(假);            返回布尔变量;
        }
    }

i'd like to store multiple values of blocks into an integer in the same way as i can convert an ip into an int. My problem is that i need to do this for n blocks, not only 4. Also i need to specifiy the maximum value of each block, which is allways the same for all blocks.

So, for the Example below, if i'd like to store the whole IP range my BlockCount is 4 and my BlockSize is 255, which is the max value of each block. But it seems not to work if i lower my BlockSize and/or BlockCount.

This is my first try, but it's not working correctly:

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;   
}

解决方案

The code above is my solution, it's pretty simple code, but feel free to ask clarification about it.

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() ;
    }
}

There extension method used

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 ;
        }
    }

这篇关于动态位移位/ Unshifting的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆