我想使用BCD将int转换为byte [4]数组。
有问题的int将来自设备ID,他需要通过serialport与设备通话。
是否有任何预制功能可以做到这一点,或者你能给我一个简单的方法吗?
示例:
int id= 29068082
会输出:
byte[4]{0x82, 0x80, 0x06, 0x29};
答案 0 :(得分:7)
使用此方法。
public static byte[] ToBcd(int value){
if(value<0 || value>99999999)
throw new ArgumentOutOfRangeException("value");
byte[] ret=new byte[4];
for(int i=0;i<4;i++){
ret[i]=(byte)(value%10);
value/=10;
ret[i]|=(byte)((value%10)<<4);
value/=10;
}
return ret;
}
这基本上是它的工作原理。
(一个优化是预先将每个字节设置为0 - 这在.NET分配新数组时隐式完成 - 并在值达到0时停止迭代。后一个优化不在代码中完成另外,如果可行的话,一些编译器或汇编器提供了一个除法/余数例程,允许在一个除法步骤中检索商和余数,这是一个通常不需要的优化。)
答案 1 :(得分:1)
可能是一个包含此循环的简单解析函数
i=0;
while (id>0)
{
twodigits=id%100; //need 2 digits per byte
arr[i]=twodigits%10 + twodigits/10*16; //first digit on first 4 bits second digit shifted with 4 bits
id/=100;
i++;
}
答案 2 :(得分:1)
与Peter O相同的版本,但在VB.NET中
Public Shared Function ToBcd(ByVal pValue As Integer) As Byte()
If pValue < 0 OrElse pValue > 99999999 Then Throw New ArgumentOutOfRangeException("value")
Dim ret As Byte() = New Byte(3) {} 'All bytes are init with 0's
For i As Integer = 0 To 3
ret(i) = CByte(pValue Mod 10)
pValue = Math.Floor(pValue / 10.0)
ret(i) = ret(i) Or CByte((pValue Mod 10) << 4)
pValue = Math.Floor(pValue / 10.0)
If pValue = 0 Then Exit For
Next
Return ret
End Function
这里的技巧是要注意,简单地使用pValue / = 10会对值进行舍入,所以如果参数为“16”,则字节的第一部分将是正确的,但是除法的结果将是2(1.6将被四舍五入)。因此我使用Math.Floor方法。