将十六进制转换为浮点数,反之亦然

时间:2014-01-24 02:07:22

标签: c arrays floating-point hex

我试图编写一个算法来将十六进制数转换为浮点数,反之亦然。这是一个赋值的一部分,该程序应该接收一个以' 0x'开头的8位十六进制数字。或浮点数,并使用计算机内置的IEEE 754功能'将数字转换为十六进制或浮点数。代码应该在C。

我的方法如下。将用户的输入存储为字符串。将输入char数组传递给一个方法,该方法通过检查数组的前两个位置来检查它是否是十六进制数,该位置应为0和X(假设所有十六进制数都以这种方式传递)。如果是这种情况,那么我检查十六进制是否是适当的形式,即0-15范围之外的数字或数字不是太多(也考虑到ABCDEF惯例)。

所以,我的问题是,我不知道如何将此数组转换回可用于转换为浮点数的数字。我想过使用sscanf把它变成一个漂浮物但是我不太了解C并且没有在网上找到任何好的来源

有人能指出我正确的方向吗?我还想过将用户输入同时存储为字符串和数字,但我不确定这是否可行。

以下是两个表格检查功能和不完整的主要方法:

int is_hex(char arr[])
{
    if (arr[0] == '0' && (arr[1] == 'x' || arr[1] == 'X')) {
        return 1;
    }
    return 0;
}

int check_if_good(char arr[])
{
    if (is_hex(arr)) {
        int len = strlen(arr);
        for (int i = 2; i < len; i++) {
            if ((arr[i] > 'f' && arr[i] <= 'z') || (arr[i] > 'F' && arr[i] <= 'Z')) {
                return 0;
            }
        }
    }

    return 1;
}

int main(int argc, const char * argv[])
{
    float x;
    char input[30];
    scanf("%s", input);
    printf("%s", input);
    return 0;
}

如果有人也能告诉我什么&#39;%x&#39;意味着我真的很感激。根据我的理解,它允许我以十六进制形式收集数字,但我可以将它们存储在整数和浮点数中吗?非常感谢你的帮助。

- 编辑:floris的额外代码。我试图在不使用任何额外库的情况下解决此问题,因此您无法使用stdint lib。

char input[30];
scanf("%s", input);
if(check_if_good(input)){  //Ignore this if-statement.
    printf("Input is in hex form");
}
int num = convert_hex_string(input); // this function works perfectly. It return the int form of the hex.
double f = *((double*)&num);
printf("%f\n", f);

5 个答案:

答案 0 :(得分:8)

如果您确实想知道特定十六进制字符串表示什么浮点数,您可以将字符串转换为整数,然后查看假设它包含浮点数的地址。以下是如何运作的:

#include <stdint.h>
#include <stdio.h>

int main(void) {
  char myString[]="0x3f9d70a4";
  uint32_t num;
  float f;
  sscanf(myString, "%x", &num);  // assuming you checked input
  f = *((float*)&num);
  printf("the hexadecimal 0x%08x becomes %.3f as a float\n", num, f);
}

这产生输出

the hexadecimal 0x3f9d70a4 becomes 1.230 as a float

正如所料。有关详细信息,请参阅my answer to your other question about a related topic

还应该很容易看到如何反向执行上述操作 - 从浮点数开始,并获得十六进制表示。

答案 1 :(得分:2)

如果您被允许使用库函数,请尝试atoi(arr)或sscanf(arr + 2,&#34;%x&#34;,&amp; num)

如果您想手动解析字符串,请考虑如何转换十进制数字。例如,转换&#34; 2987&#34;到整数......

int n = 0;
n += 1000 * 2;
n += 100  * 9;
n += 10   * 8;
n += 1    * 7;

现在将该技术应用于十六进制。这是一个执行单个ascii字符的代码片段:

int char_to_int(char c) {
   if (c >= '0' && c <= '9') return c - '0';
   if (c >= 'A' && c <= 'F') return c - 'A' + 10;
   return 0; /* oops, something else... */
}

答案 2 :(得分:1)

如果input的形式为:“0x ......”那么

float f;
long l;

l = strtol(input, (char**)NULL, 16);
f = (float)l;

printf("%f", f);

瓦尔特

答案 3 :(得分:1)

将十六进制或浮点字符的字符串转换为float

float StringToFloat(const char *s) {
  // OP's is_hex()
  if ((*s == '0') && ((*s == 'X') || (*s == 'x'))) {
    unsigned long ul = strtoul(d, NULL, 16);
    return  (float) ul;
  }
  double d = atof(s, NULL);
  return (float) d;
}
// Error handling omitted.

float转换为十六进制字符串:

// return 1 on error
int StringToFloat(char *dest, float x) {
  float y = roundf(x);
  if ((x != y) || (y >= 4294967296.0f) || (y < 0.0f)) return 1;
  sprintf(dest, "0x%lx", (unsigned long) y);
  return 0;
}

将没有库函数的十六进制字符串转换为floatunsigned long
假设ASCII)。

// Substitute unsigned long for float as desired.
// Error return handing is then different.
float HexStringToFloat(const char *s) {
  if ((*s != '0') || ((*s != 'X') && (*s != 'x'))) {
    return NAN;  // Not-a-number macro from math.h
  }
  float x = 0;
  int ch;
  while ((ch = *s++) != '\0') {
    static const char HexDigit[] = "0123456789ABCDEFabcdef";
    int i = 0;
    while (1) {
      if (HexDigit[i] == '\0') return NAN;
      if (HexDigit[i] == ch) break;
      i++; 
    }
    if (i >= 16) i -= 6;
    x *= 16;
    x += i;
  }
  return x;
}

答案 4 :(得分:0)

您需要使用乘法或位操作。在执行了描述的边界/十六进制检查后,执行以下操作:

float x = 0;
for(i=0;i<8;i++)
{
 x += getDecimalValue(inputArray[i+2]) << (4*(7-i))
}

这是未经测试的代码&amp;你需要进行从char到十进制值的转换(A = 10,B = 11等)。该按位运算与将十六进制字符的十进制等值乘以2 ^ numberOfBits相同。这个答案是假设最左边的十六进制是最重要的(Big endian),反转小的endianess操作。