我试图在big endian文件中写入带符号的整数值。
我正在使用此代码:
int32_t swap_int32( int32_t val )
{
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF );
return (val << 16) | ((val >> 16) & 0xFFFF);
}
它可以正常负值,但我有一些正值的问题:
-5给了我:
$> hexdump OUTPUT
ff ff ff fb
哪个是正确的
但是1337给了我:
$> hexdump OUTPUT
00 00 05 39
而不是(预期)00 00 39 05。
无论如何都要对待这两种情况并获得正确的结果吗? 谢谢你。
答案 0 :(得分:3)
使用htonl时有问题吗?
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
字节中的值应该保持不变,所以即使你想要一个有符号的值,只要你把它读回一个有符号的类型,你就不需要签名,你就不应该丢失数据。 (正如mctylr所述,网络秩序是大端的。)
#include <arpa/inet.h>
#include <stdio.h>
int main(int argc, char** argv) {
int32_t pos = 1337;
int32_t neg = -123;
printf("host-endian: %d => 0x%08x %d => 0x%08x \n",
pos, pos, neg, neg);
uint32_t big_endian_pos = htonl(pos);
uint32_t big_endian_neg = htonl(neg);
printf("Big-endian: %d => 0x%08x %d => 0x%08x \n",
pos, big_endian_pos, neg, big_endian_neg);
}
我的小端主机上的输出:
[tmp]$ gcc endian.c && ./a.out
host-endian: 1337 => 0x00000539 -123 => 0xffffff85
Big-endian: 1337 => 0x39050000 -123 => 0x85ffffff
答案 1 :(得分:1)
至少应该在你的功能中强制转换为“无符号”。
作为替代方案,您始终可以使用网络宏“htons()”(16位)和“htonl()”(32位)将主机转换为网络(big-endian)字节顺序。
答案 2 :(得分:0)
网络字节顺序是大端。
POSOX UNIX有htonl(),htons()和朋友可以满足您的需求。他们保证任何系统都有大端。
答案 3 :(得分:0)
在* BSD和Linux系统上,您可以在byteorder(9)
小主机上使用bswap_32()
功能,包括#include <sys/endian.h> /* other platforms may need: sys/param.h endian.h or byteswap.h */
#include <stdint.h>
uint32_t in, out;
out = bswap_32(in);
。
stdlib.h
在小端MS Windows系统上,{{1}}中包含endian,即使它不是标准版。
否则,可以在Internet上轻松找到各种_byteswap_ulong
。
和StackOverflow