Conversia unui șir hexazecimal la un întreg în mod eficient în C?

În C, care este cel mai eficient mod de a converti un șir de hexaj cifre într-un cod binar unsigned int sau unsigned long ?

De exemplu, dacă am 0xFFFFFFFE , vreau un int cu valoarea base10 4294967294 .

0
fr hi bn

9 răspunsuri

Incearca asta:

#include 
int main()
{
    char s[] = "fffffffe";
    int x;
    sscanf(s, "%x", &x);
    printf("%u\n", x);
}
0
adăugat
Este genial. Nu am mai văzut această metodă înainte.
adăugat autor Cloud Cho, sursa

You want strtol or strtoul. See also the Unix man page

0
adăugat

De ce este o soluție de cod care funcționează   obtinut votul? Sigur, e urât   ...

Poate că, pe lângă faptul că este urât, nu este educativ și nu funcționează . De asemenea, bănuiesc că, ca mine, majoritatea oamenilor nu au puterea de a edita în prezent (și de a judeca după rangul necesar - niciodată nu va).

Utilizarea unei matrice poate fi bună pentru eficiență, dar acest lucru nu este menționat în acest cod. De asemenea, nu ia în considerare semnele superioare și minuscule, astfel încât nu funcționează pentru exemplul furnizat în întrebare. FFFFFFFE

0
adăugat

@Eric

De ce este o soluție de cod care funcționează votat în jos? Sigur, este urât și nu ar putea fi cel mai rapid mod de a face acest lucru, dar este mai instructiv să spui "strtol" sau "sscanf". Dacă încercați singur, veți învăța ceva despre cum se întâmplă lucrurile sub capota.

Nu cred că soluția ar fi trebuit să fie votată, dar presupunerea mea de ce se întâmplă este pentru că este mai puțin practică. Ideea cu votarea este că răspunsul "cel mai bun" va pluti în vârf și, în timp ce răspunsul dvs. ar putea fi mai instructiv cu privire la ceea ce se întâmplă sub capota (sau într-o manieră care s-ar putea întâmpla), cu siguranță nu este cel mai bun mod de a parsa numere hex într-un sistem de producție.

Din nou, nu cred că este ceva în neregulă cu răspunsul dvs. din punct de vedere educațional și cu siguranță n-aș fi votat (și nu l-am). Nu vă descurajați și opriți postarea doar pentru că unii oameni nu au plăcut unul dintre răspunsurile dvs. S-a întâmplat.

Mă îndoiesc că răspunsul meu vă face să vă simțiți mai bine în privința votării dvs., dar știu că nu este deosebit de distractiv când întrebați de ce este votat ceva și nimeni nu răspunde .

0
adăugat
În august 2008, site-ul a fost nou și comentariile nu au fost implementate .
adăugat autor Derek Park, sursa
-1 Există un motiv pentru care avem comentarii ...
adăugat autor alternative, sursa

@Eric

Speram să văd un vrăjitor C să posteze ceva foarte cool, ceva asemănător cu ceea ce am făcut, dar mai puțin verbose, în timp ce îl fac "manual".

Ei bine, eu nu sunt C guru, dar iată ce am venit:

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

Initial aveam mai multe masuratori de bijuterii in loc de comparatii, insa ma indoiesc serios despre masuratorile bitmashing-ului mai rapid decat comparatia cu hardware-ul modern.

0
adăugat
Ai citit? "Nu am compilat acest lucru, așa că aș fi putut face unele greșeli destul de mari." Deci nu, nu am testat-o.
adăugat autor Derek Park, sursa
Acolo te duci. Am făcut-o. Pentru înregistrare, a fost deja tratată cu litere mici prin instrucțiunea "c & = 0xDF". A fost rupt în mai multe moduri, totuși.
adăugat autor Derek Park, sursa
Patru plângeri: 1) Nu se compilează. 2) Id nu se ocupă cu litere mici 3) Nu funcționează (A => 1). 4) Caracterele nevalide sunt ignorate !. Ai testat-o?
adăugat autor Martin York, sursa
A cincea plângere: Dacă programați în ANSI C (și nu aveți garanția că aveți un set de caractere de execuție bazate pe ASCII), nu există nicio garanție că 'A' + 1 == 'B' code> ('a' & 0xDF) == ('A' & 0xDF) .
adăugat autor Roland Illig, sursa

De parca se intampla adesea, intrebarea dumneavoastra sufera de o eroare terminologica/ambiguitate grava. În limbajul comun, de obicei nu contează, dar în contextul acestei probleme specifice este foarte important.

Vedeți, nu există nici un fel de "valoare hex" și "valoare zecimală" (sau "număr hexadecimal" și "număr zecimal"). "Hex" și "decimal" sunt proprietăți ale reprezentărilor ale valorilor. Între timp, valorile (sau numerele) nu au o singură reprezentare, deci nu pot fi "hex" sau "zecimal". De exemplu, 0xF și 15 în sintaxa C sunt două reprezentări diferite ale aceluiași număr .

Aș sugera că întrebarea dvs., așa cum este aceasta, sugerează că trebuie să convertiți reprezentarea hexagonală ASCII a unei valori (adică un șir) într-o reprezentare zecimală ASCII a unei valori (alt șir). O modalitate de a face aceasta este folosirea unei reprezentări întregi ca una intermediară: în primul rând, convertiți reprezentarea hexagonală ASCII la un întreg cu o dimensiune suficientă (folosind funcțiile din grupul strto ... , ca strtol ), apoi convertiți întregul în reprezentarea zecimală ASCII (folosind sprintf ).

Dacă nu este ceea ce trebuie să faceți, atunci trebuie să vă clarificați întrebarea, deoarece este imposibil să vă dați seama de modul în care este formulată întrebarea dvs.

0
adăugat
Am citit, de asemenea, întrebarea ca șir hexagonal -> șir zecimal, dar că nu se potrivește cu celelalte răspunsuri. Am editat întrebarea pentru a se potrivi cu răspunsul acceptat și cele mai multe alte răspunsuri. Întrebarea cu șirul de șir este obscură, dar mă face să mă întreb dacă se poate face fără a trece printr-un întreg binar ca pas intermediar (de exemplu, pentru cifre prea mari pentru a se potrivi într-un uint64_t ). add-with-carry un șir de cifre zecimale suge foarte mult, totuși, probabil că nu.
adăugat autor Peter Cordes, sursa

În prezent, aceasta funcționează numai cu litere mici, dar este foarte ușor să o facă să funcționeze cu ambele.

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

strlength = hexNumber.length();

for (i=0;i="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";
0
adăugat

Încercați acest lucru pentru a converti de la Decimal la Hex

    #include
    #include

    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
adăugat
zecimal-> hex este mai ușor: puteți utiliza o căutare de tabelă pentru a converti dintr-un număr întreg de 4 biți într-o cifră hexagonală, fără un comutator gigantic. char hextable [] = {'0', '1', ..., 'A', 'B', ... F '}; în loc de printf ! De asemenea, primul comutator are un bug: "B" este acolo pentru 11 și 12, de aceea 16-> "F" . /palma peste fata
adăugat autor Peter Cordes, sursa

Hexadecimal la zecimal. Nu o rulați pe compilatoarele online, pentru că nu va funcționa.

#include
void main()
{
    unsigned int i;
    scanf("%x",&i);
    printf("%d",i);
}
0
adăugat