c# << >>

今天在代码阅读中,遇到了DI、DO流类型转换,其中,每八个DI、DO为一个板块,需要将其转换为二进制。将数据进行解析。

为什么要用二进制进行解析呢?因为在计算机中,二进制更易于转换,基本运算规则简单。在计算机中,二进制为1和0。

那么先了解下二进制吧,2的零次方为1,2的一次方为2,2的二次方为四,2的三次方为8,依次类推。那么,我们随便举一个数字,比如67,那么这个数字转换为二进制为01000011

这个是怎么转换的呢?首先是

0 + 1 + 0 + 0 + 0 + 0 + 64 + 0 = 67

2的0次 + 2的1次 + 2的6次 =0 + 1 + 64 = 67;

那么接下来说一下>> <<是什么,以下代码均赋注释:

            uint ercifangNum_Cheng1 = 0 << 4;    // 0*2的4次方多少  0
            uint ercifangNum_Cheng2 = 1 << 4;  // 1*2的4次方     16
            uint ercifangNum_Cheng3 = 2 << 4;  // 2*2的4次方      32
            uint ercifangNum_Cheng4 = 3 << 4;  // 3*2的4次方      48
            double testNum1 = 2 << 5;            // 2*2的5次方      64
            double testNum2 = 3 << 6;            // 3*2的6次方      192

            //ercifangNum_Cheng1 除以2的一次方
            var r1 = ercifangNum_Cheng1 >> 1;      
            //ercifangNum_Cheng2 除以2的一次方  
            var r2 = ercifangNum_Cheng2 >> 1;    
            //ercifangNum_Cheng3 除以2的一次方
            var r3 = ercifangNum_Cheng3 >> 1;    
            //ercifangNum_Cheng4 除以2的四次方        
            var r4 = ercifangNum_Cheng4 >> 4;    

 



var r1 = ercifangNum_Cheng1 >> 1; //ercifangNum_Cheng1 除以2的一次方
var r2 = ercifangNum_Cheng2 >> 1; //ercifangNum_Cheng2 除以2的一次方
var r3 = ercifangNum_Cheng3 >> 1; //ercifangNum_Cheng3 除以2的一次方
var r4 = ercifangNum_Cheng4 >> 4; //ercifangNum_Cheng4 除以2的四次方
那么要实现以上di、do版该怎么实现? 

    static void Main(string[] args)
        { 
                List<IO_Info> infoList = new List<IO_Info>();
                DIO[] diinfo = new DIO[] { 
                new DIO() { Id=0,Value=1},
                new DIO { Id=1,Value=1},
                new DIO { Id=2,Value=0},
                new DIO { Id=3,Value=0},
                new DIO { Id=4,Value=0},
                new DIO { Id=5,Value=0},
                new DIO { Id=6,Value=1},
                new DIO { Id=7,Value=0},
                new DIO { Id=8,Value=1},
                new DIO { Id=9,Value=1}
         };
            DIO[] doinfo = new DIO[] {
                new DIO() { Id=0,Value=1},
                new DIO { Id=1,Value=0},
                new DIO { Id=2,Value=0},
                new DIO { Id=3,Value=1},
                new DIO { Id=4,Value=0},
                new DIO { Id=5,Value=1},
                new DIO { Id=6,Value=1},
                new DIO { Id=7,Value=1},
                new DIO { Id=8,Value=0},
                new DIO { Id=9,Value=1},
                new DIO { Id=10,Value=1},
                new DIO { Id=11,Value=0}
            };
            //因为DI、DO数量不等,DI可能比DO多,DO也可能比DI多
            int count = Math.Max(diinfo.Length, doinfo.Length);

            IO_Info ioboard = null;
            uint div = 0;
            uint dov = 0;
            for (int i = 0; i < count; i++)
            {
                if (diinfo.Length > i)
                {
                    //如果value值为1,则ut的值为2的id次方,若value值为0,则ut值为0
                    uint ut = ((uint)diinfo[i].Value << (diinfo[i].Id ));
                    div += ((uint)diinfo[i].Value << (diinfo[i].Id ));
                }
                if (doinfo.Length > i)
                {
                    uint ut = ((uint)doinfo[i].Value << (doinfo[i].Id ));
                    dov += ((uint)doinfo[i].Value << (doinfo[i].Id ));
                }
            }
            //每八个为一版,判断有几版,进行赋值
            var Ioboard_nums = count / 8 + 1;
            for (int i = 0; i < Ioboard_nums; i++)
            {
                ioboard = new IO_Info();
                ioboard.Ioboard_num = i;

                ioboard.DI = (int)((div >> (i * 8)) & 0xFF);
                ioboard.DO = (int)((dov >> (i * 8)) & 0xFF);

                infoList.Add(ioboard);
                ioboard = null;
            }

            var inboards = new List<IOBoard>();

            if (infoList != null)
            {
                inboards.AddRange(infoList.Select(signal => new IOBoard()
                {
                    DI = signal.DI,
                    DO = signal.DO,
                    Name = $"第{signal.Ioboard_num}板",
                    NO = signal.Ioboard_num,
                }));
            }

            foreach (var item in inboards)
            {
                Console.WriteLine($"DI:{item.DI},\nDO:{item.DO},\n第几版:{item.Name},\n编号:{item.NO}");
            }
            Console.WriteLine("div:" + div.ToString() +  "\r\ndov:" + dov.ToString());
            Console.ReadKey();
        }



    }


    public class DIO
    {
        public int Id { get; set; }

        public int Value { get; set; }
        public override string ToString()
        {
            return $"Id:{Id},Value:{Value}";
        }
    }


    public class IO_Info
    {
        public int Ioboard_num { get; set; }
        public int DI { get; set; }
        public int DO { get; set; }
    }


    public struct IOBoard
    {
        public int NO;

        public string Name;

        public int DI;

        public int DO;
    }        

  

以上代码便是其实现过程了,其中运用了>> <<来进行二进制的计算

注:其中,c#还提供了另外的算法计算次方,例如x的y次方可以通过math.Pow(x,y)来实现

posted @ 2022-10-27 16:18  小浩~  阅读(165)  评论(0编辑  收藏  举报