c函数根据字节顺序以特定顺序合并字节
c function to merge bytes in a specific order depended on endianness
我希望能够合并来自两个无符号长参数的字节,正好取一半字节,以第二个参数的最低有效字节开始的一半和第一个参数的其余部分。
例如:
x = 0x89ABCDEF12893456
y = 0x76543210ABCDEF19
result_merged = 0x89ABCDEFABCDEF19
首先,我需要检查我工作的系统是小端还是大端。我已经写了一个函数来检查它,叫做 is_big_endian().
现在我知道 char char *c = (char*) &y
会给我存储在最大内存地址的字节。
现在,我想使用 AND(&) 按位运算符来合并 x 和 y 字节,但我无法使用它,因为我真的不知道“long”的大小是多少,它可以是32 或 64 位系统不同,所以我不能真正使用固定大小。
这意味着我不能使用任何位掩码,例如:
(y & 0x00000000ffffffff) | (x & 0xffffffff00000000);
我不允许使用 long long、uint_fast64_t 或 reinterpret_cast 或任何其他“外部”东西。
我在想:
- 使用字节移位
- 使用数组存储位并运行在此数组上循环。
所以我写了这段代码,在这里我可以只使用“sizeof”来找到 long 的大小而不关心它是 32 位还是 64 位系统。
unsigned long merge(unsigned long x, unsigned long int y)
{
char* charX = (char*)&x;
char* charY = (char*)&y;
if (is_big_endian == 0){
// it's a little endian machine
for (int i=0; i<(sizeof(unsigned long))/2; i++){
*charX<<1;
*charY>>1;
}
}
else
{
for (int i=0; i<(sizeof(unsigned long))/2; i++){
*charX>>1;
*charY<<1;
}
}
return (x | y);
}
如果那是一个小端系统,我已经移动了 y 位的右侧,因为 LSB 离左边位最远。
如果这是一个大端系统,则相反。
但效果不是很好,输出为:0xffffffffbbcdff5f
如有任何帮助,我们将不胜感激。
与字节顺序无关,你可以这样做。
unsigned long merge(unsigned long x, unsigned long y)
{
if(sizeof x == 4)
return (x & 0xFFFF0000ul) | (y & 0x0000FFFFul);
else
return (x & 0xFFFFFFFF00000000ul) | (y & 0x00000000FFFFFFFFul);
}
你也可以使用条件编译
unsigned long merge(unsigned long x, unsigned long y)
{
#if ULONG_MAX == 0xFFFFFFFFul
return (x & 0xFFFF0000ul) | (y & 0x0000FFFFul);
#else
return (x & 0xFFFFFFFF00000000ul) | (y & 0x00000000FFFFFFFFul);
#endif
}
我希望能够合并来自两个无符号长参数的字节,正好取一半字节,以第二个参数的最低有效字节开始的一半和第一个参数的其余部分。
例如:
x = 0x89ABCDEF12893456
y = 0x76543210ABCDEF19
result_merged = 0x89ABCDEFABCDEF19
首先,我需要检查我工作的系统是小端还是大端。我已经写了一个函数来检查它,叫做 is_big_endian().
现在我知道 char char *c = (char*) &y
会给我存储在最大内存地址的字节。
现在,我想使用 AND(&) 按位运算符来合并 x 和 y 字节,但我无法使用它,因为我真的不知道“long”的大小是多少,它可以是32 或 64 位系统不同,所以我不能真正使用固定大小。
这意味着我不能使用任何位掩码,例如:
(y & 0x00000000ffffffff) | (x & 0xffffffff00000000);
我不允许使用 long long、uint_fast64_t 或 reinterpret_cast 或任何其他“外部”东西。
我在想:
- 使用字节移位
- 使用数组存储位并运行在此数组上循环。
所以我写了这段代码,在这里我可以只使用“sizeof”来找到 long 的大小而不关心它是 32 位还是 64 位系统。
unsigned long merge(unsigned long x, unsigned long int y)
{
char* charX = (char*)&x;
char* charY = (char*)&y;
if (is_big_endian == 0){
// it's a little endian machine
for (int i=0; i<(sizeof(unsigned long))/2; i++){
*charX<<1;
*charY>>1;
}
}
else
{
for (int i=0; i<(sizeof(unsigned long))/2; i++){
*charX>>1;
*charY<<1;
}
}
return (x | y);
}
如果那是一个小端系统,我已经移动了 y 位的右侧,因为 LSB 离左边位最远。 如果这是一个大端系统,则相反。
但效果不是很好,输出为:0xffffffffbbcdff5f
如有任何帮助,我们将不胜感激。
与字节顺序无关,你可以这样做。
unsigned long merge(unsigned long x, unsigned long y)
{
if(sizeof x == 4)
return (x & 0xFFFF0000ul) | (y & 0x0000FFFFul);
else
return (x & 0xFFFFFFFF00000000ul) | (y & 0x00000000FFFFFFFFul);
}
你也可以使用条件编译
unsigned long merge(unsigned long x, unsigned long y)
{
#if ULONG_MAX == 0xFFFFFFFFul
return (x & 0xFFFF0000ul) | (y & 0x0000FFFFul);
#else
return (x & 0xFFFFFFFF00000000ul) | (y & 0x00000000FFFFFFFFul);
#endif
}