gpt4 book ai didi

c++ - 在 Big Endian 和 Little Endian 机器中解释 32 位整数的混淆

转载 作者:太空宇宙 更新时间:2023-11-04 02:34:36 24 4
gpt4 key购买 nike

我正在将代码从 Big Endian Machine 重写到 Little Endian 机器。

假设有一个名为a 的变量,它是一个 32 位整数,用于保存当前时间戳(用户请求的当前时间戳)。

在大端机中,现在的代码是这样的:

uint32 a = current_timestamp_of_user_request;
uint8 arr[3] = {0};
arr[0] = ((a >> (8 * 2)) & 0x000000FF);
arr[1] = ((a >> (8 * 1)) & 0x000000FF);
arr[2] = ((a >> (8 * 0)) & 0x000000FF);

现在,当我为小端机编写相同的逻辑时,我可以使用相同的代码(方法 a),还是应该以这种方式转换代码(我们称此方法为 b)?

uint32 a = current_timestamp_of_user_request;
uint32 b = htonl(a);
uint8 arr[3] = {0};
arr[0] = ((b >> (8 * 2)) & 0x000000FF);
arr[1] = ((b >> (8 * 1)) & 0x000000FF);
arr[2] = ((b >> (8 * 0)) & 0x000000FF);

我写这个程序是为了验证:

#include<stdio.h>
#include<stdlib.h>


void main() {
long int a = 3265973637;
long int b = 0;
int arr[3] = {0,0,0};

arr[0] = ((a >> (8 * 2)) & 0x000000FF);
arr[1] = ((a >> (8 * 1)) & 0x000000FF);
arr[2] = ((a >> (8 * 0)) & 0x000000FF);

printf("arr[0] = %d\t arr[1] = %d\t arr[2] = %d\n", arr[0], arr[1], arr[2]);

b = htonl(a);

arr[0] = ((b >> (8 * 2)) & 0x000000FF);
arr[1] = ((b >> (8 * 1)) & 0x000000FF);
arr[2] = ((b >> (8 * 0)) & 0x000000FF);

printf("After htonl:\n");
printf("arr[0] = %d\t arr[1] = %d\t arr[2] = %d\n", arr[0], arr[1], arr[2]);

}

结果:

Result with little endian machine:

bgl-srtg-lnx11: /scratch/nnandiga/test>./x86
arr[0] = 170 arr[1] = 205 arr[2] = 133
After htonl:
arr[0] = 205 arr[1] = 170 arr[2] = 194

Result with big endian machine:
arr[0] = 170 arr[1] = 205 arr[2] = 133
After htonl:
arr[0] = 170 arr[1] = 205 arr[2] = 133

看起来没有转换为大端顺序,相同的逻辑(没有 htonl())在填充数组 arr 时给出了准确的结果。现在,如果我希望数组在小端和大端机器中相同(小端结果应该与大端结果完全相同),你能回答我是否应该使用 htonl() 吗? .

最佳答案

您最初编写的代码将在大端和小端机器上执行您想要的操作。

如果a的值是0x00123456,那么0x12进入arr[0]0x34 进入 arr[1]0x56 进入 arr[2]。无论机器的字节顺序如何,都会发生这种情况。

当您使用 >>>& 运算符时,它们对相关表达式的 value 进行运算,而不是 该值的表示

当您调用 htonl 时,您会更改值以匹配特定的表示形式。所以在小端机器上 htonl(0x00123456) 将产生值 0x56341200。然后,当您对该值进行操作时,您会得到不同的结果。

当以字节形式读取或写入使用多个字节的数字表示形式时,字节序很重要,即写入磁盘、通过网络或写入/写入字节缓冲区。

例如,如果您这样做:

uint32_t a = 0x12345678;
...
write(fd, &a, sizeof(a));

然后将 a 组成的四个字节一次一个地写入文件描述符(无论是文件还是套接字)。大端机器将按 0x120x340x560x78 的顺序写入,而小端机器将写入0x780x560x340x12

如果您希望以一致的顺序写入字节,那么您应该先调用 a = htonl(a),然后再调用 write。然后字节将始终写入0x120x340x560x78

因为您的代码对值而不是值的各个字节进行操作,所以您无需担心字节顺序。

关于c++ - 在 Big Endian 和 Little Endian 机器中解释 32 位整数的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39173695/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com