我正在尝试将表示24位十六进制数(FFFFFF)的字符串转换为其十进制等效值(-1)。任何人都可以帮助我理解为什么以下代码不返回-1?
谢谢,LC
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char temp_str[] = "FFFFFF";
long value;
value = strtol(temp_str, NULL, 16);
printf("value is %ld\n", value);
}
答案 0 :(得分:3)
看起来您的输入是数字的24位2的补码表示,但strtol
不能以这种方式处理负数(即使它确实如此,也无法知道您的意思一个24位的表示)。它仅根据-
符号的存在来确定其输出的符号。
您可以在strtol
:
if (value > 0x7fffff)
value -= 0x1000000;
当然,这只适用于24位表示,其他大小则需要不同的常量。
答案 1 :(得分:2)
黑客的喜悦涵盖了sign extension下的内容。
对于24位数字, sign 位是右边第24位,如果设置了,则十六进制值为0x800000
。
这本书暗示了这些:
((x + 0x800000) & 0xFFFFFF) - 0x800000
or
((x & 0xFFFFFF) xor 0x800000) - 0x800000
从你的问题我会说你的号码永远不会超过24位,所以我会在你的代码中使用第二个选项,如下所示:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char temp_str[] = "FFFFFF";
long value;
value = strtol(temp_str, NULL, 16);
value = (value ^ 0x800000) - 0x800000; // Notice that I'm not using the & 0xFFFFFF since I assumed that the number won't have more than 24 bits.
printf("value is %ld\n", value);
}
修改1:
我担心我原来的答案虽然在技术上合理,却没有回答提出的问题。
有谁能帮我理解为什么以下代码不会返回-1?
其他人已经在我回答的时候已经涵盖了这一点,但无论如何我会在这里重申。
您的字符串是"FFFFFF"
,它由6个十六进制数字组成。每个十六进制数字代表4位,因此您的字符串代表24位数字。
您的变量long value
的类型为长,通常与您的CPU字宽(32位或64位)相对应。由于这些天long
可以是32位或64位,具体取决于您的架构,除非您提供正确数量的十六进制数字,否则无法保证获得-1
。
如果你机器上的long
是32位,那么两件事情都是真的:
sizeof(long)
将返回4 "FFFFFFFF"
将返回-1 如果你机器上的long
是64位,那么有两件事情是真的:
sizeof(long)
将返回8 "FFFFFFFFFFFFFFFF"
将返回-1 <强>题外话强>
然后,这引导我走上一条完全不同的道路。我们可以对此进行概括,并创建一个为您的机器构造字符串的程序,以便它始终从字符串返回-1。#include #include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const char* ff = "FF";
char temp[sizeof(long) * 2 + 1]; // Ensure that the string can store enough hex digits so that we can populate the entire width of long. Include 1 byte for '\0'
int i;
long value;
/* Fill the temp array with FF */
for (i = 0; i < sizeof(long); ++i)
{
strcpy(&temp[i * 2], ff);
}
value = strtol(temp, NULL, 16);
printf("value of %s is %ld\n", temp, value);
}
这是获得-1结果的不好方法,因为clear选项只是使用
long value = -1;
但我会认为这只是一次学术活动。
答案 2 :(得分:0)
不要认为现在作为一台电脑,只需要通过十进制(FFFFFF)十进制使用普通的数学思维。这不是两个补充否定符号。
答案 3 :(得分:0)
因为您在32位或64位计算机上运行此程序,而不是24位计算机。 0xffffff实际上是0x00ffffff,十进制是16777215。
-1的十六进制表示为0xffffffff或0xffffffffffffffff。