2014-01-24 387 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; 
} 
相關問題