2014-01-24 345 views
3

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

我的方法如下。用户将输入存储为字符串。将输入字符数组传递给一个方法,通过检查数组的前两个位置(它应该是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; 
} 

如果有人也可以告诉我这个“%X”的基本意味着我将不胜感激。根据我的理解,我可以用十六进制形式收集数字,但是我可以将它们存储在整数和浮点数中吗?非常感谢您的帮助。

- 编辑:floris的额外代码。我试图解决这个问题,而不使用任何额外的库,所以你不能使用stdint库。

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); 
+0

“%x”表示您编写数字的十六进制值。例如'unsigned char i = 10; printf(“%x”,i);'会给'a'。 –

+0

请注意,您需要执行'printf(“%lf”,f);''当'f'是一个'double' ... – Floris

回答

3

如果你真的想知道什么浮点数是由特定的十六进制字符串来表示,可以将字符串转换为整数,然后看这个地址假装它包含一个浮点数。下面是如何将工作:

#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

也应该很容易看出你如何做到反向 - 以浮点数开始,并获得十六进制表示。

+0

Hey Floris!我试图在没有库的情况下实现您的代码。一切工作正常,我能够通过循环内容和做一堆乘法将十六进制字符串转换为其整数值。但是,现在当我尝试打印它的浮点数时,我总是得到0.0000,你知道什么可能是错误的吗?谢谢! – macalaca

+0

有点难以猜测......你能展示重现你问题的关键线吗? ''只是确保'uint32_t'类型存在并且是四个字节长 - 你可以看到'sizeof(int)== 4'在这种情况下你可以使用'int'而且你不需要'stdint .h'。否则,请改用'long int'。但是显示一些代码。如果需要,编辑您的问题。 – Floris

+1

我在最后添加了我的代码!谢谢。 – macalaca

0

您需要使用乘法或位操作。你做你的边界/六角后检查你所描述的,做这样的事情:

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

这是未经测试的代码&你需要做的,从字符转换为十进制值(A = 10,B = 11 ECT) 。该按位操作与将十六进制字符的十进制等效值乘以2^numberOfBits相同。这个答案假设最左边的十六进制是最重要的(大端),反转操作的小端。

+1

减去48将'0'(0x30或48)变为'0';如果'> 9',然后减去7取'A'(65 == 48 + 10 + 7)到'10'。 –

1

如果input的形式是: “0X ......” 然后

float f; 
long l; 

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

printf("%f", f); 

瓦尔特

1

如果你被允许使用的库函数,尽量的atoi(ARR)或sscanf的(arr + 2,“%x”,& num)

如果您想手动解析字符串,请考虑如何转换十进制数字。例如,将“2987”转换为整数...

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... */ 
} 
+0

'arr + 2'可以很简单的'arr'。 '“%x”'会消耗'“0x”'。 – chux

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; 
} 

将字符串转换为Ø f十六进制字符转换为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[] = "ABCDEFabcdef"; 
    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; 
} 
相关问题