1. 程式人生 > >將十六進位制資料轉換成有符號十進位制數

將十六進位制資料轉換成有符號十進位制數

方法一: #define _READ_HEXADECIMAL_DATA_ #define HEXADECIMAL_ROW_NUM 32 void main() { char tempBuffer1[10]; char tempBuffer2[10]; char tempBuffer3[10]; #ifdef _READ_HEXADECIMAL_DATA_ for (k=0,m=0; k<HEXADECIMAL_ROW_NUM; k++,m++) { //原始資料低位在前,高位在後。讀取到tempBuffer1陣列中,則tempBuffer1[3] 、tempBuffer1[2] 、tempBuffer1[1] 、tempBuffer1[0] 儲存的是十六進位制數值從高位到低位的排列 tempBuffer1[0] = tempBuffer[1+m*18]; tempBuffer1[1] = tempBuffer[0+m*18]; tempBuffer1[2] = tempBuffer[4+m*18]; tempBuffer1[3] = tempBuffer[3+m*18]; tempBuffer1[4] = '\0'; // C語言規定以字元'\0'作為字串結束的標誌
tempBuffer2[0] = tempBuffer[7+m*18]; tempBuffer2[1] = tempBuffer[6+m*18]; tempBuffer2[2] = tempBuffer[10+m*18]; tempBuffer2[3] = tempBuffer[9+m*18]; tempBuffer2[4] = '\0'; tempBuffer3[0] = tempBuffer[13+m*18]; tempBuffer3[1] = tempBuffer[12+m*18]; tempBuffer3[2] = tempBuffer[16+m*18]; tempBuffer3[3] = tempBuffer[15+m*18]; tempBuffer3[4] = '\0'; AccTemp[0] = TranslateData(tempBuffer1); //函式呼叫 AccTemp[1] = TranslateData(tempBuffer2); AccTemp[2] = TranslateData(tempBuffer3); fprintf(fout, "%d,%d,%d\n", AccTemp[0], AccTemp[1], AccTemp[2]); } #endif } int16 TranslateData(const char *buff) { int i; int32 iDATA = 0; uint8 TempNum; int32 temp = 0; for(i=0; i<4; i++) { if (buff[i]>57) { TempNum = (buff[i] - 55); // 相當於TempNum = (buff[i] - 'a' + 10); 'a'的ASCII值是65
} else { TempNum = (buff[i] - 48); // 相當於TempNum = (buff[i] - '0' ); '0'的ASCII值是48 } temp = (int32)(pow(16.0, i)); iDATA += TempNum * (temp); //按照按位計數制,計算數值 } if(iDATA > 0x7fff) { iDATA = iDATA - 65536; //正整數溢位時,對數值進行反轉 } return iDATA; } 表1 符號-數值與2的補碼錶示
4位符號數值表示 4位補碼錶示
7 0111 7 0111
6 0110 6 0110
5 0101 5 0101
4 0100 4 0100
3 0011 3 0011
2 0010 2 0010
1 0001 1 0001
+0 0000 0 0000
-0 1000 -1 1111
-1 1001 -2 1110
-2 1010 -3 1101
-3 1011 -4 1100
-4 1100 -5 1011
-5 1101 -6 1010
-6 1110 -7 1001
-7 1111 -8 1000
方法二:網上參考程式碼 /*練習2-3 編寫函式htoi(s),將十六進位制數字組成的字串(包含可選的字首0x或0X)轉換為與之等價的整型值。 字串允許包含的數字包括:0~9、a~f、A~F。*/
  1. #include <stdio.h>
  2. int htoi(char s[]);  
  3. int main()  
  4. {  
  5.     int a = htoi("1234");  
  6.     int b = htoi("0x1f");  
  7.     int c = htoi("0XAD");  
  8.     printf("十進位制:%d, 十六進位制:%#x\n",a,a);  
  9.     printf("十進位制:%d, 十六進位制:%#x\n",b,b);  
  10.     printf("十進位制:%d, 十六進位制:%#x\n",c,c);  
  11.     return 0;  
  12. }  
  13. int htoi(char s[])  
  14. {  
  15.     int n,i ;  
  16. n = 0;  
  17.     for (i=0;s[i]!='\0';i++)  
  18.     {  
  19.         if (s[i]=='0'&&(s[i+1]=='x'||s[i+1]=='X'))  
  20.         {  
  21. i = i+2;  
  22.         }  
  23.         if((s[i]>='0'&&s[i]<='9'))  
  24.         {  
  25. n = n*16+s[i]-'0';  
  26.         }  
  27.         else if (s[i]>='a'&&s[i]<='f')  
  28.         {  
  29. n = n*16+10+s[i]-'a';  
  30.         }  
  31.         else if (s[i]>='A'&&s[i]<='F')  
  32.         {  
  33. n = n*16+10+s[i]-'A';  
  34.         }  
  35.     }  
  36.     return n;  
  37. }  
int htoi(const char *s) { if( !s )return 0; if( *s == '0' ) { s++; if( *s == 'x' || *s == 'X' )s++; } int n = 0; while( *s ) { n <<= 4; if( *s <= '9' ) n |= ( *s & 0xf ); else n |= ( (*s & 0xf) + 9 ); s++; } return n; } int main(int argc, char* argv[]) { printf("%x\n", htoi("0xa")); printf("%x\n", htoi("0xab")); printf("%x\n", htoi("0xabc")); printf("%x\n", htoi("0x0a0b")); printf("%x\n", htoi("a")); printf("%x\n", htoi("ab")); printf("%x\n", htoi("abc")); printf("%x\n", htoi("12ab")); return 0; } 方法三:直接處理一個數的補碼,計算得到有符號十進位制數 (1)拼接字元。把兩個無符號的字元,拼接成一個有符號的十進位制數,方法是:將高位的字元左移8位,然後位或低8位的字元。 (2)判斷符號。單獨提取最高位的位。方法:要提取的變數位與0x8000 (3)將補碼錶示的負數,轉成有符號的十進位制數。方法:要轉換的變數先減1,再反轉所有位(反轉所有位的意思是每一個0變為1,每一個1變為0),然後提取除了最高位之外的所有位,最後在變數前面加上負號(-)。
總結:按位轉換有符號十進位制數最簡單的演算法是反轉所有位,然後加1。上面的程式碼實現跟這個最簡單的演算法在轉換原理上是一致的。