【问题标题】:Convert Byte[]{LSB-0,MSB-0,LSB-1,MSB-1...LSB-N,MSB-N} to Int[](int-0,int-1,int-N)将 Byte[]{LSB-0,MSB-0,LSB-1,MSB-1...LSB-N,MSB-N} 转换为 Int[](int-0,int-1,int-N)
【发布时间】:2018-08-17 14:01:47
【问题描述】:

我希望将 LSB、MSB 的字节数组转换为 int 的数组

目前,我正在使用 for 循环并单独转换每组值,

void ConvertToInt(int OutArray[], byte InArray[], int InSize)
{
  for(int i=0; InSize/2>=i; i++)
  {
    int value = InArray[2*i] + (InArray[2*i+1] << 8);
    OutArray[i]=value;
  }
}

但是,鉴于:

  1. OutArray[] 是为此特定目的在父函数中创建的。
  2. 此操作后我不需要InArray[]

有没有更有效的方法可以直接将我的字节数组转换为 Int 数组?

【问题讨论】:

  • 在内存使用或速度方面效率高吗?
  • 你能给出一些示例输入及其预期输出吗?
  • 我一直在寻找速度方面的东西,但我正在使用ATmega2560 所以我的内存也有限。

标签: c++ arrays arduino


【解决方案1】:

字节对数组进行运算,然后组装成整数:

void ConvertToInt(int OutArray[], byte InArray[], int InSize)
{
  int * p_output = &OutArray[0];
  for (size_t i = 0; i < inSize; ++i)
  {
    byte lsb = InArray[i++];
    byte msb = InArray[i];
    int value = (msb << 8) | lsb;
    *p_output++ = value;
  }
}

您可能需要转换为更大的整数,具体取决于警告级别:

for (size_t i = 0U; i < InSize; i += 2U)
{
  const byte lsb = InArray[i + 0U];
  const byte msb = InArray[i + 1U];
  const int lsb_as_int(static_cast<int>(lsb));
  const int msb_as_int(static_cast<int>(msb));
  *p_output++ = (msb_as_int * 256) + lsb_as_int;
}

在上面的代码中,byteint 的提升是明确的。这些变量是临时的,编译器应该简化它(所以不要担心临时变量)。此外,临时变量允许您在使用调试器时查看中间值。

在优化或恐慌之前,在调试和发布(优化)版本中打印出编译器生成的汇编语言。一个好的编译器应该将循环内容优化为几条指令。

【讨论】:

  • 鉴于我的经验,我决定采用您的第一个答案,因为我相信它最符合我的要求。经过测试,我想指出值线应该是int value = (lsb &lt;&lt; 8)|msb
【解决方案2】:

如果你的机器是小端,那么这可以在 O(1) 时间和额外的内存复杂度内完成。

int16_t *ToInt(byte inArray[])
{
  return reinterpret_cast<int16_t*>(inArray);
}

如果您希望它在一个新数组中,或者您的机器是大端,您必须遍历所有元素。在这种情况下,您可以获得的最佳结果是 O(n) 时间复杂度。

解决这个问题的唯一方法是将原始数组包装在一个访问器类中,该访问器类将在字节对之间转换为 int。这样的包装器将加快前几次访问的时间,但如果在某些时候必须读取所有数组,那么惰性求值将比从头开始转换数组花费更多。

从积极的方面来说,包装器仅花费 O(1) 额外的内存。另外,如果要将数组保存为字节,则不必转换。

class as_int {
public:
   class proxy
   {
      public:
          proxy & operator=(int16_t value)
          {
             pair_[0] = value& 255;
             pair_[1] = ((unsigned)value >> 8) & 255;
             return *this;
          }
         operator int16_t() ......
      private:
         proxy(byte*pair): pair_(pair) {}
         friend class as_int;
   };
   as_int(byte *arr, unsigned num_bytes) 
    : arr_(arr), size_(num_bytes/2)
   {}

   int16_t operator[] const (unsigned i)
   {
      assert(i < size);
      byte *pair = arr_ + (i*2);
      return pair[0] + (pair[1]<<8);
   }
   proxy operator[] (unsigned i)
   {
      assert(i < size);
      return proxy(arr_ + (i*2));
   }
  ....

而且使用起来也很琐碎:

as_int arr(InByteArray, InSize);
std::cout << arr[3] << '\n';
arr[5] = 30000;
arr[3] = arr[6] = 500;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2011-11-09
    • 2013-05-17
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    相关资源
    最近更新 更多