我希望将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;
}
}
但是,鉴于此:
OutArray[]
。InArray[]
有没有更有效的方法将我的字节数组直接转换为Int数组?
答案 0 :(得分:0)
以 bytes 的形式在数组上进行操作,然后汇编并放置为整数:
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;
}
在上面的代码中,从byte
到int
的提升是明确的。变量是临时的,编译器应简化此操作(因此不必担心临时变量)。另外,使用临时变量,您可以在使用调试器时查看中间值。
在优化或恐慌之前,以调试和发行(优化)版本打印出编译器生成的汇编语言。一个好的编译器应该将循环内容优化为一些指令。
答案 1 :(得分:0)
如果您的计算机是低端字节序,则可以在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;