我想使用BCD将int转换为byte [2]数组。int转换为BCD字节数组
有问题的int将来自表示Year的DateTime,并且必须转换为两个字节。
是否有任何预制功能可以做到这一点,或者您能否给我一个简单的方法来做到这一点?
例如:
int year = 2010
将输出:
byte[2]{0x20, 0x10};
我想使用BCD将int转换为byte [2]数组。int转换为BCD字节数组
有问题的int将来自表示Year的DateTime,并且必须转换为两个字节。
是否有任何预制功能可以做到这一点,或者您能否给我一个简单的方法来做到这一点?
例如:
int year = 2010
将输出:
byte[2]{0x20, 0x10};
static byte[] Year2Bcd(int year) {
if (year < 0 || year > 9999) throw new ArgumentException();
int bcd = 0;
for (int digit = 0; digit < 4; ++digit) {
int nibble = year % 10;
bcd |= nibble << (digit * 4);
year /= 10;
}
return new byte[] { (byte)((bcd >> 8) & 0xff), (byte)(bcd & 0xff) };
}
当心,你问一个大端结果,这是一个有点不寻常。
这是一个可怕的蛮力版本。我相信有比这更好的方法,但无论如何它应该工作。
int digitOne = year/1000;
int digitTwo = (year - digitOne * 1000)/100;
int digitThree = (year - digitOne * 1000 - digitTwo * 100)/10;
int digitFour = year - digitOne * 1000 - digitTwo * 100 - digitThree * 10;
byte[] bcdYear = new byte[] { digitOne << 4 | digitTwo, digitThree << 4 | digitFour };
它不幸的是,快速的二进制到BCD转换是建立在x86的微处理器架构,如果你能在他们那里得到!
这里有一个稍微清洁的版本,则Jeffrey's
static byte[] IntToBCD(int input)
{
if (input > 9999 || input < 0)
throw new ArgumentOutOfRangeException("input");
int thousands = input/1000;
int hundreds = (input -= thousands * 1000)/100;
int tens = (input -= hundreds * 100)/10;
int ones = (input -= tens * 10);
byte[] bcd = new byte[] {
(byte)(thousands << 4 | hundreds),
(byte)(tens << 4 | ones)
};
return bcd;
}
你可能会想出一些疯狂的方式,使用布尔逻辑和移位......但这会更好地维护。 – 2010-03-15 15:59:47
static byte[] IntToBCD(int input) {
byte[] bcd = new byte[] {
(byte)(input>> 8),
(byte)(input& 0x00FF)
};
return bcd;
}
这不是[BCD](http://en.wikipedia.org/wiki/Binary-coded_decimal)。您只是将int转换为两个字节的数组, – 2011-08-11 16:14:45
更常见的解决方案
private IEnumerable<Byte> GetBytes(Decimal value)
{
Byte currentByte = 0;
Boolean odd = true;
while (value > 0)
{
if (odd)
currentByte = 0;
Decimal rest = value % 10;
value = (value-rest)/10;
currentByte |= (Byte)(odd ? (Byte)rest : (Byte)((Byte)rest << 4));
if(!odd)
yield return currentByte;
odd = !odd;
}
if(!odd)
yield return currentByte;
}
如果您可以计算的所有值都是整数,则不应使用小数作为输入参数。如果你需要一个十进制的内部计算它应该保持内部或如何计算'GetBytes(3.55549322);'? – Oliver 2012-02-22 13:49:46
我做了一个普通的日常在IntToByteArray贴,你可以使用这样的:
VAR yearInBytes = ConvertBigIntToBcd(2010,2);
如果他正在使用嵌入式硬件,那么Big-endian可能并不常见。 – 2010-03-15 16:09:56
非常感谢! 在这种情况下,我不认为Endian很重要,我很小心,但在这种情况下它确定。 – Roast 2010-03-15 16:18:35