gpt4 book ai didi

将十六进制字符串转换为 signed int 会在不同平台上产生不同的值

转载 作者:行者123 更新时间:2023-12-04 10:08:22 25 4
gpt4 key购买 nike

我正在处理一个我想成为多平台的程序中的边缘情况。这是问题的摘录:

#include <stdio.h>
#include <string.h>

void print_bits(size_t const size, void const * const ptr){
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;

for (i=size-1;i>=0;i--)
{
for (j=7;j>=0;j--)
{
byte = (b[i] >> j) & 1;
printf("%u", byte);
}
}
puts("");
}

int main() {

char* ascii = "0x80000000";
int myint = strtol(ascii, NULL, 16);

printf("%s to signed int is %d and bits are:\t", ascii, myint);
print_bits(sizeof myint, &myint);

return 0;
}

所以当我在 Linux 上使用 GCC 编译时,我得到了这个输出:

0x80000000 to signed int is -2147483648 and bits are:   10000000000000000000000000000000

在 Windows 上,使用 MSVC 和 MinGW 我得到:

0x80000000 to signed int is 2147483647 and bits are:    01111111111111111111111111111111

我认为 GCC 输出了正确的预期值。我的问题是,这种差异从何而来以及如何确保在所有编译器上我都能得到正确的结果?

更新

这段代码背后的原因是,我必须检查 HEX 值的 MSB(位#31)是 0 还是 1。然后,我必须得到接下来 7 位的无符号整数值(#30 到#24) 结果(如果是 0x80000000,这 7 位的结果应该是 0:

    int msb_is_set = myint & 1;
uint8_t next_7_bits;

next_7_bits = myint >> 24; //fine on GCC, outputs 0 for the next 7 bits
#ifdef WIN32 //If I do not do this, next_7_bit will be 127 on Windows instead of 0
if(msb_is_set )
next_7_bits = myint >> 1;
#endif

附言这是在同一台机器上(i5 64 位)

最佳答案

您在这里处理不同的数据模型。

Windows 64 使用LLP64,这意味着只有long long 并且指针是64 位的。 由于 strtol转换为 long,因此转换为32bit值,32bit有符号整数中的 0x80000000为负。

Linux 64 使用 LP64,所以 longlong long 和指针都是 64 位的。 我猜你现在明白这里发生了什么 ;)


感谢评论,我意识到我最初的回答是错误的。不同的结果确实与这些平台上的不同模型有关。 但是:在LP64 模型的情况下,您可以转换为无法保存值的有符号类型,这是实现定义的。 int 在两个平台上都是 32 位的,而 32 位的 int 不能容纳 0x80000000。所以正确的答案是:你不应该期望你的代码在 Linux64 上有任何结果。在 Win64 上,由于 long 只有 32 位,strtol() 正确返回 0x80000000LONG_MAX,这恰好是只比您输入的小一个。

关于将十六进制字符串转换为 signed int 会在不同平台上产生不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44365740/

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