Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中无符号64位数字的字节顺序转换问题_C_Gcc_Uint32 - Fatal编程技术网

C语言中无符号64位数字的字节顺序转换问题

C语言中无符号64位数字的字节顺序转换问题,c,gcc,uint32,C,Gcc,Uint32,我正在玩little endian/big endian转换,发现有些东西有点混乱,但也很有趣 在第一个示例中,使用位移位转换uint32\u t类型的字节顺序没有问题。它基本上将一个uint32\u t整数转换为uint8\u t数组,并尝试访问每个字节和位移位 示例#1: 为了使其工作,我必须将每个字节提取到一个uint64_t中,这样我就可以在没有任何错误的情况下进行位移位,如下面的示例3所示 示例#3: uint64\u t htonl2(uint64\u t x) { uint64字节

我正在玩little endian/big endian转换,发现有些东西有点混乱,但也很有趣

在第一个示例中,使用位移位转换
uint32\u t
类型的字节顺序没有问题。它基本上将一个
uint32\u t
整数转换为
uint8\u t
数组,并尝试访问每个字节和位移位

示例#1:

为了使其工作,我必须将每个字节提取到一个
uint64_t
中,这样我就可以在没有任何错误的情况下进行位移位,如下面的示例3所示

示例#3:

uint64\u t htonl2(uint64\u t x)
{
uint64字节1=x&0xff00000000000000;
uint64字节2=x&0x00ff000000000000;
uint64字节3=x&0x0000ff0000000000;
uint64字节4=x&0x000000ff00000000;
uint64字节5=x&0x00000000ff000000;
uint64字节6=x&0x0000000000ff0000;
uint64字节=x&0x000000000000ff00;
uint64字节8=x&0x00000000000000ff;
返回(uint64_t)(字节1>>56;字节2>>40;字节3>>24;字节4>>8|

当在表达式中使用时,类型小于
int
的字节5值将提升为
int
。假设平台上的
int
为32位,则在大多数情况下,在转换32位值时,此操作都有效。如果将1位移到符号位,则此操作不起作用

在64位的情况下,这意味着您正试图将一个值移位超过其未定义行为的位长度


在这两种情况下,您都需要将每个字节强制转换为
uint64\t
,以允许移位正常工作。

s[0]
表达式有一个8位宽的整数类型,当移位运算符对其进行操作时,该类型被提升为32位无符号整数–因此
s[0]
uint8\u t
将被提升为
int
。它将是有符号的,而不是无符号的,并且它将是
int
的任何宽度,现在通常是32位,但C标准允许是16位或更多。这将不起“OK”作用因为,如果
uint8\u t
的高位打开且
int
为32位,则24位的移位将溢出
int
中可表示的值的范围,并且行为不由C标准定义。
uint32_t htonl(uint32_t x)
{
    uint8_t *s = (uint8_t*)&x;
    return (uint32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
}
uint64_t htonl(uint64_t x)
{
    uint8_t *s = (uint8_t*)&x;
    return (uint64_t)(s[0] << 56 ......);
}
uint64_t htonll2(uint64_t x)
{
    uint64_t byte1 = x & 0xff00000000000000;
    uint64_t byte2 = x & 0x00ff000000000000;         
    uint64_t byte3 = x & 0x0000ff0000000000;
    uint64_t byte4 = x & 0x000000ff00000000;
    uint64_t byte5 = x & 0x00000000ff000000;
    uint64_t byte6 = x & 0x0000000000ff0000;                                                                                              
    uint64_t byte7 = x & 0x000000000000ff00;
    uint64_t byte8 = x & 0x00000000000000ff;

    return (uint64_t)(byte1 >> 56 | byte2 >> 40 | byte3 >> 24 | byte4 >> 8 |
                      byte5 << 8  | byte6 << 24 | byte7 << 40 | byte8 << 56);
}