[英]How to convert a QByteArray in little endian format to a unsigned long
[英]How to simply reconstruct numbers from a buffer in little endian format
假设我有:
typedef unsigned long long uint64;
unsigned char data[BUF_SIZE];
uint64 MyPacket::GetCRC()
{
return (uint64)(data[45] | data[46] << 8 |
data[47] << 16 | data[48] << 24 |
(uint64)data[49] << 32| (uint64)data[50] << 40 |
(uint64)data[51] << 48| (uint64)data[52] << 56);
}
只是想知道是否有更清洁的方法。 我尝试对uint64变量使用memcpy,但这给了我错误的值。 我想我需要反过来。 数据为小端格式。
使用移位或序列的最大优点是,不管主机是大端还是小端,它都可以工作。
当然,您总是会调整表达式。 我个人尝试连接“ pairs”,一次是两个字节,然后是两个short,最后是两个long,因为这将帮助编译器生成更好的代码。
好吧,也许更好的主意是交换订单+演员表?
typedef unsigned long long uint64;
unsigned char data[BUF_SIZE];
uint64 MyPacket::GetCRC()
{
uint64 retval;
unsigned char *rdata = reinterpret_cast<unsigned char*>(&retval);
for(unsigned i = 0; i < 8; ++i) rdata[i] = data[52-i];
return retval;
}
这是我自己的一个,与@ x13n提供的类似。
uint64 MyPacket::GetCRC()
{
int offset=45;
uint64 crc;
memcpy(&crc, data+offset, 8);
//std::reverse((char*)&crc, (char*)&crc + 8); // if this was a big endian machine
return crc;
}
说实话,您所拥有的没有多大错。 它会工作,而且很快。 我要做的是将其格式化为更好的可读性:
uint64 MyPacket::GetCRC()
{
return (uint64) data[45] |
(uint64) data[46] << 8 |
(uint64) data[47] << 16 |
(uint64) data[48] << 24 |
(uint64) data[49] << 32 |
(uint64) data[50] << 40 |
(uint64) data[51] << 48 |
(uint64) data[52] << 56;
}
我猜您的另一个选择是改为循环执行:
uint64 MyPacket::GetCRC()
{
const int crcoffset = 45;
uint64 crc = 0;
for (int i = 0; i < 8; i++)
{
crc |= (uint64)data[i + crcoffset] << (i * 8);
}
return crc;
}
这可能会导致非常相似的汇编(因为编译器可能会针对如此小的循环进行循环展开),但在我看来,这有点难以理解,因此您可以更好地利用已有的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.