strtol()返回错误数值:MSB为1的十六进制数转换异常排查
问题原因分析
核心问题是有符号整数溢出与类型范围不匹配:
数值超出int的取值范围
假设你的系统使用32位有符号int,其取值范围是-2147483648到2147483647。你输入的0x80dd354f作为无符号数是2161980751,这个值已经超过了32位有符号int的最大值2147483647。strtol返回值的类型转换溢出
strtol返回的是long类型,当你把超出int范围的long值赋值给int变量时,会触发有符号整数溢出。根据C标准,这种行为属于未定义行为,但多数编译器会将其“饱和”到int的最大值,也就是你看到的2147483647。MSB=1的特殊性
十六进制数最高位(MSB)为1时,对应的十进制值必然大于等于2^31(即2147483648),刚好超过32位有符号int的上限,因此触发溢出;而MSB为0的数值(如0x06866aed)对应的十进制值小于2^31,在int的范围内,所以转换结果符合预期。
解决方案建议
若需处理无符号大数值,可将返回类型和
result变量改为unsigned int,同时用strtoul替代strtol:unsigned int stringToInt(char* string) { unsigned int result = 0; if (string[0] == '0' && string[1] == 'x') result = strtoul(string + 2, NULL, 16); else result = (unsigned int)atoi(string); printf("String = %s, result = %u\n", string, result); return result; }若必须使用有符号int,且输入的十六进制数代表有符号负数,那么
0x80dd354f对应的有符号int值应为-207678597,这需要你明确输入的语义是有符号数。
内容的提问来源于stack exchange,提问作者Amit Davidi
相关产品推荐
相关产品推荐

