2013-07-26 12 views
1

我有一个56字节的寄存器可用在一些我想存储引擎小时的eeprom。目前我只用3个字节增加一个60秒的定时器,然后下载信息(该数字在发送之前很少超过9999分钟)。56个字节和99个问题来保存日期和编号

问题是我需要将日期与此关联。每次开车时,我都需要开始我的小时记录,但是我需要确定那个小时哪个小时增加了。

因此,如果我有一个字节[56]数组,那么存储日期(或只是一个小时的日期)最简单的方法是什么,后面是一个数字,并且能够区分它们?

对于传输,我需要一种方法来遍历数组并提取日期或小时以及小时数。

任何想法都会很棒,谢谢。

在报告最终结果将类似于:

06:00 - 38分钟 09:00 - 60分钟 10:00 - 60分钟 等

+0

56个字节是房间的负荷......你只需要拿出某种形式的数据表示 –

+0

的精选想那就是我,你能想到的办法?我是新来的这种类型的效率... –

+0

看一看MSDN文章,我只是张贴在我下“更新”的答案 –

回答

1

好这里是一个想法一个计划,以适应你所需要的所有数据在你的56字节(事实上我们可以适应多达11个日期和时间到56字节):

假设你不希望这个系统持续超过一千年,我们可以将2013年的第一部分定义为2013年分为两个时间段和一年。

  • 时期:5个比特(或一个字节),从而允许0-31
  • 年份:7个比特(或一个字节),从而允许0-99
  • 天:9位(两个字节),从而允许0-365
  • 小时:5位(一个字节),允许0-24
  • 二:12位(两个字节),允许0-3600

现在,你可以简单地使用7个字节,每递增的值,并会允许您存储多达8个日期和时间,但是你可以创建一个结构体,并将位单元的每个位进一步压缩以进一步压缩它,从而允许你将它分成40位(或者5个字节),并将它们分成11个日期。

你也可能下降时代,如果你真的临时抱佛脚,但上述方案将允许您使用日期工作高达3199.

我肯定还有其他的,更紧凑的方式,即毫秒数自01.01。 1970年以后说未来几年可能会减少几位,但会缩短代码的寿命,但我没有看到实际值。

一些示例代码(已经更新为使用BitArray为布尔内部是一个字节(?!),但BitArray实际上是位......在OPS情况:

OP应该注意,我认为很重要您希望存储每小时驾驶的分钟数量,但是这会需要更多的空间(每个小时的记录或每天的开始和停止记录,以指示他们开始和停止的分钟数(在开始后必须停止)。下面的代码将允许您记录在给定的一天中驾驶多少分钟。

using System; 
using System.Collections; 

namespace BitBangingDate 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CompactDateManipulator x = new CompactDateManipulator(); 
      Console.WriteLine(x.ToString()); 
      x.Month = 7; 
      x.Day = 27; 
      x.Minute = 1234; 
      Console.WriteLine(x.ToString()); 

      var bitArr = x.GetCompactedArray(); 

      CompactDateManipulator x1 = new CompactDateManipulator();//create new blank date to test whether can be reiitialised from BitArray 

      x1.ReinitialiseDateFromBitArray(bitArr); 

      Console.WriteLine(x1.ToString()); 
     } 
    } 

    class CompactDateManipulator 
    { 
     CompactDate _date = new CompactDate(); 

     public int Month 
     { 
      get 
      { 
       return BoolArrayToInt(_date.month); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.month, value); 
      } 
     } 
     public int Day 
     { 
      get 
      { 
       return BoolArrayToInt(_date.day); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.day, value); 
      } 
     } 
     public int Minute 
     { 
      get 
      { 
       return BoolArrayToInt(_date.minute); 
      } 
      set 
      { 
       IntToBoolArray(ref _date.minute, value); 
      } 
     } 

     public BitArray GetCompactedArray() 
     { 
      return _date.GetFullArray(); 
     } 

     public void ReinitialiseDateFromBitArray(BitArray arr) 
     { 
      _date.SetDate(arr); 
     } 

     //utility methods 
     void IntToBoolArray(ref bool[] bits, int input) 
     { 
      var len = bits.Length; 
      for (int i = 0; i < len; i++) 
      { 
       bits[i] = (input & 1) == 1 ? true : false; 
       input >>= 1; 
      } 
     } 
     int BoolArrayToInt(bool[] bits) 
     { 
      if (bits.Length > 32) throw new ArgumentException("Can only fit 32 bits in a int"); 
      int r = 0; 
      for (int i = 0; i < bits.Length; i++) 
      { 
       if (bits[i]) r |= 1 << i; 
      } 
      return r; 
     } 
     public override string ToString() 
     { 
      return String.Format("Stored Date mm/dd/ss: {0}/{1}/{2}", Month, Day, Minute); 
     } 
    } 

    class CompactDate 
    { 
     //Layout Month(5) Day(9)  Minute (12) 
     //  11111  111111111 111111111111 
     public bool[] month = new bool[5]; 
     public bool[] day = new bool[9]; 
     public bool[] minute = new bool[12]; 
     public BitArray GetFullArray() 
     { 
      int fullLen = month.Length + day.Length + minute.Length; 
      BitArray full = new BitArray(fullLen); 
      int index = 0; 
      for (int i = 0; i < month.Length; i++,index++) 
      { 
       full.Set(index,month[i]); 
      } 
      for (int i = 0; i < day.Length; i++, index++) 
      { 
       full.Set(index, day[i]); 
      } 
      for (int i = 0; i < minute.Length; i++, index++) 
      { 
       full.Set(index, minute[i]); 
      } 
      return full; 
     } 
     public void SetDate(BitArray arr) 
     { 
      int index = 0; 
      for (int i = 0; i < month.Length; i++, index++) 
      { 
       month[i] = arr.Get(index); 
      } 
      for (int i = 0; i < day.Length; i++, index++) 
      { 
       day[i] = arr.Get(index); 
      } 
      for (int i = 0; i < minute.Length; i++, index++) 
      { 
       minute[i] = arr.Get(index); 
      } 
     } 
    } 
} 
+0

我不认为存储整个日期是必要的。我需要的只是一天,一小时以及积累的分钟数。到目前为止,我所得到的最好的结果就是只使用日和小时,而分钟数就是这个数字。类似log [0] = 913(第09天,第13小时 - 3字节),log [1] = 56(第13小时为56分钟 - 1字节)。然后log [2] = 914,log [3] = 10等。这仍然效率太低,因为这意味着我将每小时使用4个字节,这使我有14个小时来保存数据。我需要至少两天的时间。我是否在谈论这个错误? –

+0

查看如何填充比特的更新。我们可以存储26位(4个字节) –

+0

通过“天”的整个时间你的意思是一年或一个月中的哪一天天(一个需要9位的其他4)个月的 –

0

您可以用分钟表示开始时间的情况下,它不会在一个确切的时间入手,让24x60 = 1440是你必须考虑在开始时的最高数字。以二进制表示的1440是0000010110100000(2字节),因此数组的第一个元素0-1表示开始时间。接下来,你说9999分钟是运行时的可接受上限,二进制是0010011100001111(2字节),所以数组元素2-3代表运行时间。