算法--任意长度16进制相加
在开发中涉及数采部分,部分PLC的元软件地址是用16进制标识的。
例如三菱的 M1F 这样,同步时上位机端保存最好也同样记录一样名字的地址,这里就需要16进制的加减运算。
最简单的计算方式是:
(Convert.ToInt32(saddr, 16) + inc).ToString("x").ToUpper();
拓展开来,要是需要进行一个任意长度的16进制加法呢,找了一下网上也没看到有比较好的操作。
检查梳理一下思路,就是从低位到高位逐位相加,然后有进位的参与后边运算,代码如下
public string HexAdd(string first, string second) {
var src = first.ToCharArray();
var des = second.ToCharArray();
char[] res;
if (src.Length < des.Length) {
res=HexAddByChars(des.Reverse().ToArray(), src.Reverse().ToArray());
} else {
res=HexAddByChars(src.Reverse().ToArray(), des.Reverse().ToArray());
}
return res != null ? string.Concat(res.Reverse()) : string.Empty ;
}
public string HexAdd(string saddr, int inc) {
return (Convert.ToInt32(saddr, 16) + inc).ToString("x");
}
private char[] HexAddByChars(char[] a, char[] b) {
var res = new char[a.Length];
var padd = 0;
for (var i =0; i< a.Length; i++) {
if (i >= b.Length) {
res[i] = HexAddByChar(a[i], Convert.ToChar(padd.ToString()), out padd);
padd = 0;
} else {
if (padd > 0) { //低位结果有进位运算时
var sa = HexAdd(a[i].ToString(), padd);
var re = HexAdd(sa, b[i]);
if (re.Length > 1) {
padd = int.Parse(re.Substring(0, 1));
res[i] = Convert.ToChar(re.Substring(1));
} else {
res[i] = Convert.ToChar(re);
}
} else {
res[i] = HexAddByChar(a[i], b[i], out padd);
}
}
}
return res;
}
private char HexAddByChar(char a, char b, out int padd) {
padd = 0;
var tres = b=='\0'?a.ToString(): (Convert.ToInt32(a.ToString(),16) + Convert.ToInt32(b.ToString(),16)).ToString("x");
if (tres.Length > 1) {
padd = int.Parse(tres.Substring(0, 1));
}
return Convert.ToChar(tres.Length>1?tres.Substring(1):tres);
}
注意:运算需要从低位往高位推进,所以上边操作将16进制字符串分拆成数组后,需要先逆序再操作,操作完再逆序保存回来。