BCD十六进制字符串到整数

时间:2010-12-30 14:38:55

标签: c# .net numbers bcd

我能够修改Brad Christie提供的解决方案,以获得我期望的小时,分​​钟,秒,月,日和年的结果,所有这些都是BCD格式:

static Int32 GetYearFromBCD(Int32 time) 
{ 
int length = time.ToString().Length -1;
List<Int32> YearList = new List<Int32>(); 
for (Int32 i = length; i >= 0; i --) 
{ 
Int32 place = i * 4; 
Int32 val = 0x01 << place; 

Int32 curVal = (Int32)(time / val); 
if (curVal > 9 && YearList.Count > 0) 
{ 
Int32 delta = (Int32)(curVal / 10); 
YearList[YearList.Count - 1] += delta; 
curVal -= delta * 10; 
} 
YearList.Add(curVal); 
time -= curVal << place; 
} 
Int32 Year = 0; 
for (Int32 y = 0; y < YearList.Count; y++) 
Year += YearList[y] * (Int32)Math.Pow(10,(length+1 - y)-1); 
return Year; 
} 

我想提供此问题的更新。在设备运行新年后的几天之后,我能够完全确认Brad发布的代码解决方案完全符合我们的需求。

我能够证实我怀疑预期值确实是二进制编码的Decmial,我能够确认预期的值只有HEX值。一位同事能够独立地确认时间和日期,使用标准表,所以我觉得把它放到床上很舒服。

我能够确认无论出于何种原因数据的decmial值不起作用,我只能断定设备将数据作为十六进制值发送,我唯一担心的是其他应用程序是否会在类似的情况下工作方法

我很感谢大家帮忙解决这个问题,其中一些评论引导我走上一条让我弄明白的道路。

3 个答案:

答案 0 :(得分:3)

好吧,即使数字似乎没有意义,这也是我提出的结果(给出了期待的结果(来自提供的示例)。绞尽脑汁,看看它是否符合你所期望的所有结果:

static Int32 GetYearFromBCD(Int32 time)
{
    List<Int32> YearList = new List<Int32>();
    for (Int32 i = 3; i >= 0; i --)
    {
        Int32 place = i * 4;
        Int32 val = 0x01 << place;

        Int32 curVal = (Int32)(time / val);
        if (curVal > 9 && YearList.Count > 0)
        {
            Int32 delta = (Int32)(curVal / 10);
            YearList[YearList.Count - 1] += delta;
            curVal -= delta * 10;
        }
        YearList.Add(curVal);
        time -= curVal << place;
    }
    Int32 Year = 0;
    for (Int32 y = 0; y < 4; y++)
        Year += YearList[y] * (Int32)Math.Pow(10,(4 - y)-1);
    return Year;
}

我真的只是在黑暗中拍摄,因为你给的数字不是我所说的典型数字。话虽如此,你必须做出你正在接受的工作,所以:耸耸肩:。

答案 1 :(得分:1)

你真的确定你的例子是正确的吗?为什么你有一个十六进制数字,第一部分是基数10,第二部分是16?

正常会是其中之一:

  • 2010 =&gt; 0x07DA
    • 完整的十六进制
  • 2010 =&gt; 0x140A
    • 数字中途被破坏,每个部分是十六进制
  • 2010 =&gt; 0x2010
    • bcd编码在维基百科上找到(其他地方); - )

经过一些谷歌搜索并思考这是我的第一个想法:

  • 将所有内容放入BinaryReader
  • 通过调用BinaryReader.ReadByte()并将其转换为int
  • ,单独从中获取所有值
  • 首先将每个值乘以10,然后除以16
  • 将所有这些单独的值放入List<int>
  • 使用Math.Pow(value, 10 * (List.Count - indexOfValue))汇总所有这些值

答案 2 :(得分:1)

如果要将数字转换为十六进制表示,只需使用带有“x”的ToString作为参数:

2010.ToString("x")  output: "7da"

但是,如果你说2010年的预期为200A,我真的不明白你想要达到什么目标。