2008-08-13 74 views

Trả lời

13

Hãy thử điều này:

#include <stdio.h> 
int main() 
{ 
    char s[] = "fffffffe"; 
    int x; 
    sscanf(s, "%x", &x); 
    printf("%u\n", x); 
} 
+1

Thật tuyệt vời. Tôi chưa từng thấy phương pháp này trước đây. –

1

@ Eric

Tại sao là một giải pháp mã mà làm việc nhận được bình chọn xuống? Chắc chắn, nó xấu xí và có thể không phải là cách nhanh nhất để làm điều đó, nhưng nó mang tính hướng dẫn hơn là nói "strtol" hoặc "sscanf". Nếu bạn tự mình thử nó, bạn sẽ học được điều gì đó về những điều xảy ra dưới mui xe.

Tôi thực sự không nghĩ giải pháp của bạn nên được bỏ phiếu, nhưng tôi đoán là tại sao nó lại xảy ra là vì nó ít thực tế hơn. Ý tưởng bỏ phiếu là câu trả lời "tốt nhất" sẽ nổi lên trên cùng và trong khi câu trả lời của bạn có thể hướng dẫn hơn về những gì xảy ra dưới mui xe (hoặc cách nó có thể xảy ra), nó chắc chắn không phải là cách tốt nhất để phân tích cú pháp số hex trong một hệ thống sản xuất.

Một lần nữa, tôi không nghĩ có gì sai với câu trả lời của bạn từ quan điểm giáo dục, và tôi chắc chắn sẽ không (và không) bỏ phiếu. Đừng nản lòng và ngừng đăng bài chỉ vì một số người không thích một trong những câu trả lời của bạn. Nó xảy ra.

Tôi nghi ngờ câu trả lời của tôi làm cho bạn cảm thấy tốt hơn về bạn bị bỏ phiếu, nhưng tôi biết điều này đặc biệt không thú vị khi bạn hỏi tại sao một cái gì đó bị bỏ phiếu và no one answers.

+2

-1 Có một lý do chúng tôi có ý kiến ​​... – alternative

+6

Vào tháng 8 năm 2008, trang web là thương hiệu mới và * nhận xét không được triển khai *. –

0

@ Eric

Tôi đã thực sự hy vọng sẽ nhìn thấy một C phù thủy bài một cái gì đó thực sự mát mẻ, loại giống như những gì tôi đã làm nhưng ít tiết, trong khi vẫn làm việc đó "thủ công".

Vâng, tôi không có C guru, nhưng đây là những gì tôi đã đưa ra:

unsigned int parseHex(const char * str) 
{ 
    unsigned int val = 0; 
    char c; 

    while(c = *str++) 
    { 
     val <<= 4; 

     if (c >= '0' && c <= '9') 
     { 
      val += c & 0x0F; 
      continue; 
     } 

     c &= 0xDF; 
     if (c >= 'A' && c <= 'F') 
     { 
      val += (c & 0x07) + 9; 
      continue; 
     } 

     errno = EINVAL; 
     return 0; 
    } 

    return val; 
} 

Tôi ban đầu đã bitmasking hơn đang diễn ra thay vì so sánh, nhưng tôi nghiêm túc nghi ngờ bitmasking là nhanh hơn bất kỳ so sánh trên phần cứng hiện đại.

+0

Bốn khiếu nại: 1) Nó không biên dịch. 2) Id không xử lý trường hợp thấp hơn 3) Nó không hoạt động (A => 1). 4) Các ký tự không hợp lệ chỉ bị bỏ qua !. Bạn đã thử nó chưa? –

+0

Bạn đã đọc nó chưa? "Tôi đã không thực sự biên dịch điều này, vì vậy tôi có thể đã thực hiện một số sai lầm khá lớn." Vì vậy, không, tôi đã không kiểm tra nó. –

+0

Có bạn đi. Tôi vá nó lên. Đối với hồ sơ, nó đã được xử lý trường hợp thấp hơn thông qua "c & = 0xDF" tuyên bố. Tuy nhiên, nó đã bị hỏng theo nhiều cách khác. –

1

Đối với các chuỗi Hex lớn hơn như trong ví dụ tôi cần sử dụng strtoul.

0

Tại sao giải pháp mã hoạt động bị bỏ phiếu? Chắc chắn, đó là xấu xí ...

Có lẽ vì cũng như là xấu xí nó không phải là giáo dục và không làm việc. Ngoài ra, tôi nghi ngờ rằng giống như tôi, hầu hết mọi người không có quyền chỉnh sửa hiện tại (và đánh giá bởi các cấp bậc cần thiết - không bao giờ sẽ).

Việc sử dụng mảng có thể tốt cho hiệu quả, nhưng điều đó không được đề cập trong mã này. Nó cũng không có tài khoản của trường hợp trên và dưới nên nó không hoạt động cho ví dụ được cung cấp trong câu hỏi. FFFFFFFE

6

Nếu bạn không có stdlib thì bạn phải thực hiện thủ công.

unsigned long hex2int(char *a, unsigned int len) 
{ 
    int i; 
    unsigned long val = 0; 

    for(i=0;i<len;i++) 
     if(a[i] <= 57) 
     val += (a[i]-48)*(1<<(4*(len-1-i))); 
     else 
     val += (a[i]-55)*(1<<(4*(len-1-i))); 

    return val; 
} 

Lưu ý: Mã này giả định chữ hoa A-F. Nó không hoạt động nếu len vượt quá số nguyên dài nhất 32 hoặc 64bits của bạn, và không có bẫy lỗi cho các ký tự hex bất hợp pháp.

+2

'a [i] - '0'' và' a [i] -' A '+ 10' cũng sẽ hoạt động trong trường hợp hiếm hoi hệ thống của bạn đang sử dụng EBCDIC (chúng vẫn tồn tại). –

+1

''0'' và'' A'' cũng làm cho mã của bạn tự ghi lại tài liệu, cho những người không nhớ bảng ASCII. –

-3

Điều này hiện chỉ hoạt động với trường hợp thấp hơn nhưng siêu dễ dàng để làm cho nó hoạt động với cả hai.

cout << "\nEnter a hexadecimal number: "; 
cin >> hexNumber; 
orighex = hexNumber; 

strlength = hexNumber.length(); 

for (i=0;i<strlength;i++) 
{ 
    hexa = hexNumber.substr(i,1); 
    if ((hexa>="0") && (hexa<="9")) 
    { 
     //cout << "This is a numerical value.\n"; 
    } 
    else 
    { 
     //cout << "This is a alpabetical value.\n"; 
     if (hexa=="a"){hexa="10";} 
     else if (hexa=="b"){hexa="11";} 
     else if (hexa=="c"){hexa="12";} 
     else if (hexa=="d"){hexa="13";} 
     else if (hexa=="e"){hexa="14";} 
     else if (hexa=="f"){hexa="15";} 
     else{cout << "INVALID ENTRY! ANSWER WONT BE CORRECT\n";} 
    } 
    //convert from string to integer 

    hx = atoi(hexa.c_str()); 
    finalhex = finalhex + (hx*pow(16.0,strlength-i-1)); 
} 
cout << "The hexadecimal number: " << orighex << " is " << finalhex << " in decimal.\n"; 
3

Như thường lệ xảy ra, câu hỏi của bạn bị lỗi nghiêm trọng về ngôn ngữ/mơ hồ. Trong bài phát biểu chung nó thường không quan trọng, nhưng trong bối cảnh của vấn đề cụ thể này nó là cực kỳ quan trọng.

Bạn thấy đấy, không có thứ gì như "giá trị thập lục phân" và "giá trị thập phân" (hoặc "số thập lục phân" và "số thập phân"). "Hex" và "thập phân" là các thuộc tính của các đại diện giá trị. Trong khi đó, các giá trị (hoặc số) của chúng không có đại diện, vì vậy chúng không thể là "hex" hoặc "decimal". Ví dụ: 0xF15 trong cú pháp C là hai đại diện khác nhau của cùng một số.

Tôi đoán câu hỏi của bạn, cách nó được đề cập, bạn cần chuyển đổi biểu diễn hex ASCII của một giá trị (tức là một chuỗi) thành biểu diễn thập phân ASCII của một giá trị (chuỗi khác). Một cách để làm điều đó là sử dụng một biểu diễn số nguyên như một phần tử trung gian: đầu tiên, chuyển đổi biểu diễn hex ASCII thành số nguyên đủ kích thước (sử dụng các hàm từ nhóm strto..., như strtol), sau đó chuyển đổi số nguyên thành biểu diễn thập phân ASCII (sử dụng sprintf).

Nếu đó không phải là những gì bạn cần làm, thì bạn phải làm rõ câu hỏi của bạn, vì không thể hình dung ra câu hỏi của bạn được xây dựng.

+0

Tôi cũng đọc câu hỏi dưới dạng chuỗi hex -> chuỗi thập phân, nhưng không khớp với các câu trả lời khác. Tôi đã chỉnh sửa câu hỏi để phù hợp với câu trả lời được chấp nhận và hầu hết các câu trả lời khác. Chuỗi-> chuỗi câu hỏi là tối nghĩa, nhưng làm cho tôi tự hỏi nếu nó có thể được thực hiện mà không đi qua một số nguyên nhị phân như là một bước trung gian (ví dụ: cho số quá lớn để phù hợp trong một 'uint64_t'). add-with-carry xuống một chuỗi các chữ số thập phân hút rất nhiều, mặc dù, vì vậy có lẽ không. –

0

Hãy thử này để chuyển đổi từ số thập phân để Hex

#include<stdio.h> 
    #include<conio.h> 

    int main(void) 
    { 
     int count=0,digit,n,i=0; 
     int hex[5]; 
     clrscr(); 
     printf("enter a number "); 
     scanf("%d",&n); 

     if(n<10) 
     { 
      printf("%d",n); 
     } 

     switch(n) 
     { 
      case 10: 
       printf("A"); 
      break; 
      case 11: 
       printf("B"); 
      break; 
      case 12: 
       printf("B"); 
      break; 
      case 13: 
       printf("C"); 
      break; 
      case 14: 
       printf("D"); 
      break; 
      case 15: 
       printf("E"); 
      break; 
      case 16: 
       printf("F"); 
      break; 
      default:; 
     } 

     while(n>16) 
     { 
      digit=n%16; 
      hex[i]=digit; 
      i++; 
      count++; 
      n=n/16; 
     } 

     hex[i]=n; 

     for(i=count;i>=0;i--) 
     { 
      switch(hex[i]) 
      { 
      case 10: 
       printf("A"); 
       break; 
      case 11: 
       printf("B"); 
       break; 
      case 12: 
       printf("C"); 
       break; 
      case 13: 
       printf("D"); 
       break; 
      case 14: 
       printf("E"); 
       break; 
      case 15: 
       printf("F"); 
       break; 
      default: 
       printf("%d",hex[i]); 
      } 
    } 

    getch(); 

    return 0; 
} 
+0

Xem xét việc thay đổi 'void main()' thành 'int main (void)' –

+0

decimal-> hex dễ dàng hơn: bạn có thể sử dụng tra cứu bảng để chuyển đổi từ số nguyên 4 bit thành số thập phân, không có 'công tắc' khổng lồ. 'char hextable [] = {'0', '1', ..., 'A', 'B', ..., 'F'};' Và bạn có thể sử dụng 'putchar' thay vì' printf'! Ngoài ra, công tắc đầu tiên của bạn có một lỗi: '" B "' là có cho 11 và 12, đó là lý do tại sao 16-> '" F "'./facepalm –

1

Hexadecimal để thập phân. Không chạy nó trên trình biên dịch trực tuyến, bởi vì nó sẽ không hoạt động.

#include<stdio.h> 
void main() 
{ 
    unsigned int i; 
    scanf("%x",&i); 
    printf("%d",i); 
} 
+1

dis sẽ làm việc wid upper nd thấp hơn cả hai trường hợp ..... tôi đã kiểm tra nó bản thân mình nó hoạt động .... –

27

Edit: Bây giờ tương thích với MSVC, C++ và phi GNU (xem cuối).

Câu hỏi là "cách hiệu quả nhất". OP không chỉ định nền tảng, anh ta có thể biên dịch cho chip ATMEL dựa trên RISC với 256 byte bộ nhớ flash cho mã của mình.

Đối với hồ sơ, và cho những người (như tôi), những người đánh giá cao sự khác biệt giữa "Cách đơn giản nhất" và "Cách hiệu quả nhất", và những người được hưởng học tập ...

static const long hextable[] = { 
    [0 ... 255] = -1, // bit aligned access into this table is considerably 
    ['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors, 
    ['A'] = 10, 11, 12, 13, 14, 15,  // for the space conscious, reduce to 
    ['a'] = 10, 11, 12, 13, 14, 15  // signed char. 
}; 

/** 
* @brief convert a hexidecimal string to a signed long 
* will not produce or process negative numbers except 
* to signal error. 
* 
* @param hex without decoration, case insensitive. 
* 
* @return -1 on error, or result (max (sizeof(long)*8)-1 bits) 
*/ 
long hexdec(unsigned const char *hex) { 
    long ret = 0; 
    while (*hex && ret >= 0) { 
     ret = (ret << 4) | hextable[*hex++]; 
    } 
    return ret; 
} 

Nó đòi hỏi không có thư viện bên ngoài, và nó nên được nhanh chóng blindingly.Nó xử lý chữ hoa, chữ thường, ký tự không hợp lệ, đầu vào hex lẻ (ví dụ: 0xfff) và kích thước tối đa chỉ bị giới hạn bởi trình biên dịch.

Đối với trình biên dịch không phải GCC hoặc C++ hoặc trình biên dịch sẽ không chấp nhận khai báo hextable ưa thích.

Thay thế báo cáo kết quả đầu tiên với điều này (dài, nhưng phù hợp hơn) phiên bản:

static const long hextable[] = { 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1, 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 
}; 
+0

Tôi có đúng trong suy nghĩ 'hextable' initialisation mã là giả mã (nếu như vậy nó có giá trị chỉ mà ra), hoặc là một số cú pháp initialisation mảng bí truyền tôi không quen thuộc với? –

+1

Biên dịch và tìm hiểu! (spoiler: nó hoạt động) – davehayden

+0

Nó không được biên dịch với Android ndk-build. – hB0

0
#include "math.h" 
#include "stdio.h" 
/////////////////////////////////////////////////////////////// 
// The bits arg represents the bit say:8,16,32...                            
///////////////////////////////////////////////////////////// 
volatile long Hex_To_Int(long Hex,char bits) 
{ 
    long Hex_2_Int; 
    char byte; 
    Hex_2_Int=0; 

    for(byte=0;byte<bits;byte++) 
    { 
     if(Hex&(0x0001<<byte)) 
      Hex_2_Int+=1*(pow(2,byte)); 
     else 
      Hex_2_Int+=0*(pow(2,byte)); 
    } 

    return Hex_2_Int; 
} 
/////////////////////////////////////////////////////////////// 
//                             
///////////////////////////////////////////////////////////// 

void main (void) 
{ 
    int Dec; 
    char Hex=0xFA; 
    Dec= Hex_To_Int(Hex,8); //convert an 8-bis hexadecimal value to a number in base 10 
    printf("the number is %d",Dec); 
} 
+0

Mã chuyển đổi hệ thập lục phân sang dạng thập phân ... không mã hóa phức tạp .. đơn giản nhưng hoạt động. –

+2

Thiên Chúa của tôi, đây có lẽ là việc thực hiện tồi tệ nhất của hex đến tháng mười hai mà tôi từng thấy. 'pow' nghiêm túc? Biết rằng nó thường được thực hiện như là 'pow (a, b) = exp (b * log (a))'. Nhưng ngay cả khi không, chuyển đổi số nguyên thành gấp đôi đã là một hoạt động nặng, đặc biệt là trên các bộ vi xử lý hiện đại. –

+0

Lưu ý rằng 'Hex_To_Int' lấy đầu vào của nó như là một bitstring base-2 được lưu trữ trong một' long'. Việc chuyển đổi chuỗi thập lục phân thành số nguyên xảy ra vào thời gian biên dịch! "Chuyển đổi" chỉ là một không có chi phí rất cao có thể được viết tốt hơn là 'trả về Hex'. –

1

Đối với AVR vi điều khiển tôi đã viết hàm sau, trong đó có ý kiến ​​có liên quan để làm cho nó dễ hiểu:

/** 
* hex2int 
* take a hex string and convert it to a 32bit number (max 8 hex digits) 
*/ 
uint32_t hex2int(char *hex) { 
    uint32_t val = 0; 
    while (*hex) { 
     // get current character then increment 
     char byte = *hex++; 
     // transform hex character to the 4bit equivalent number, using the ascii table indexes 
     if (byte >= '0' && byte <= '9') byte = byte - '0'; 
     else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10; 
     else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;  
     // shift 4 to make space for new digit, and add the 4 bits of the new digit 
     val = (val << 4) | (byte & 0xF); 
    } 
    return val; 
} 

Ví dụ:

char *z ="82ABC1EF"; 
uint32_t x = hex2int(z); 
printf("Number is [%X]\n", x); 

Will đầu ra: enter image description here

+0

Điều này thậm chí còn kém hiệu quả hơn mã Java ... – Alex

+0

Tôi không nghĩ vậy, nhưng có lẽ bạn quên cung cấp một số đối số. – radhoo

0

Trong C bạn có thể chuyển đổi một số thập lục phân sang thập phân bằng nhiều cách. Một cách là truyền số thập lục phân sang số nguyên. Cá nhân tôi thấy điều này đơn giản và nhỏ.

Đây là mã mẫu để chuyển đổi số thập lục phân thành số thập phân với trợ giúp truyền.

#include <stdio.h> 

int main(){ 
    unsigned char Hexadecimal = 0x6D; //example hex number 
    int Decimal = 0; //decimal number initialized to 0 


     Decimal = (int) Hexadecimal; //conversion 

    printf("The decimal number is %d\n", Decimal); //output 
    return 0; 
} 
Các vấn đề liên quan