将FFFFFF转换为十进制值(C语言)

时间:2013-12-25 11:45:25

标签: c

我正在尝试将表示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);
}

4 个答案:

答案 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位,那么两件事情都是真的:

  1. sizeof(long)将返回4
  2. 使用"FFFFFFFF"将返回-1
  3. 如果你机器上的long是64位,那么有两件事情是真的:

    1. sizeof(long)将返回8
    2. 使用"FFFFFFFFFFFFFFFF"将返回-1
    3. <强>题外话

      然后,这引导我走上一条完全不同的道路。我们可以对此进行概括,并创建一个为您的机器构造字符串的程序,以便它始终从字符串返回-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。