假设我有8个无符号字符,我想将它们转换为一个无符号长整型。
例如,如果所有的字符都等于0xFF,则无符号长整型将等于0xFFFFFFFFFFFFFFFF。
使用C或C++,最有效的方法是什么?
假设我有8个无符号字符,我想将它们转换为一个无符号长整型。
例如,如果所有的字符都等于0xFF,则无符号长整型将等于0xFFFFFFFFFFFFFFFF。
使用C或C++,最有效的方法是什么?
例如:
unsigned char buffer[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
unsigned long long target;
memcpy(&target, buffer, sizeof target);
buffer
的所有元素值不相同,则结果将取决于字节顺序(小端 vs. 大端)。unsigned long long
确切地为8个字节。虽然这很常见,但并不保证。(一个字节恰好为8位也不是保证,它可能更多。根据定义,unsigned char
为1个字节。)<stdint.h>
或<cstdint>
和uint64_t
将始终提供8个字节。 - Jason64 / CHAR_BIT
字节。但是如果你假设CHAR_BIT==8
,那么是的,uint64_t
总是8个字节(如果存在的话!)。 - Keith Thompsonchar
并不一定被定义为一个字节,这意味着 uint64_t
可能无法容纳整个字符串。使用 unsigned long long
时大小不匹配可能会更糟。 - Jasonchar
在 C 和 C++ 中的定义是一个字节。一个字节不一定是八位的八进制数;它可以更大。unsigned long long
至少有 64 位,但可以更大。另一方面,具有 CHAR_BIT > 8
的系统很少见(主要是 DSP),我从未见过大小不是恰好 64 位的 unsigned long long
。 - Keith Thompson你可以直接使用赋值操作代替memcpy复制位
unsigned char buffer[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
unsigned long long l = 0;
for (int i = 0; i < 8; ++i) {
l = l | ((unsigned long long)buffer[i] << (8 * i));
}
我认为这是与字节序无关的。
非常抱歉我之前的回答有些愚蠢,应该更仔细地阅读问题。希望这个回答更有帮助。转换的方式取决于字节数组中 long long 表示的字节序是否与您所使用的架构相匹配。
C++:
#include <iostream>
#include <cstring>
using namespace std;
// Assuming ca is at least 8 bytes, the size of long long, interpret the
// first 8 bytes as long long.
// differentEndian == true means the endianness of the machine is
// different from the representation in ca.
long long getLongLong( unsigned char * ca, bool differentEndian )
{
long long retVal;
if (differentEndian)
{
for (int i = 0; i < 4; i++)
{
unsigned char _tmpCh = ca[i];
ca[i] = ca[7-i];
ca[7-i] = _tmpCh;
}
}
retVal = *reinterpret_cast<unsigned long long *>(ca);
return retVal;
}
int main()
{
unsigned char cArray[] = {0xff, 0x1, 0x70, 0x2, 0x61, 0x3, 0x52, 0x4};
unsigned long long ll = getLongLong( cArray, false );
cout << "Result for same endian: " << hex << ll << " or " << dec << ll << endl;
ll = getLongLong( cArray, true );
cout << "Result for different endian: " << hex << ll << " or " << dec << ll << endl;
return 0;
}
C:
#include <stdio.h>
#include <string.h>
// Assuming ca is at least 8 bytes, the size of long long, interpret the
// first 8 bytes as long long.
// differentEndian != 0 means the endianness of the machine is
// different from the representation in ca.
long long getLongLong( unsigned char * ca, int differentEndian )
{
long long retVal;
if (differentEndian)
{
int i;
for (i = 0; i < 4; i++)
{
unsigned char _tmpCh = ca[i];
ca[i] = ca[7-i];
ca[7-i] = _tmpCh;
}
}
memcpy( &retVal, ca, sizeof(long long));
return retVal;
}
int main()
{
unsigned char cArray[] = {0xff, 0x1, 0x70, 0x2, 0x61, 0x3, 0x52, 0x4};
unsigned long long ll = getLongLong( cArray, 0 );
printf("Result for same endian: %llx or %llu\n", ll, ll);
ll = getLongLong( cArray, 1 );
printf("Result for different endian: %llx or %llu\n", ll, ll);
return 0;
}
两个版本的输出结果均为:
Result for same endian: 4520361027001ff or 311315039429591551
Result for different endian: ff01700261035204 or 1837509111016818739
reinterpret_cast
。 - Thomas Matthews