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)来实现