Pensiamo alla metà del compito per un momento: la conversione da una base di stringa n a una senza firma lunga, dove n è una potenza di 2 (base 2 per binario e base 16 per esadecimale).
Se il tuo input è sano, questo lavoro non è altro che un confronto, un surrogato, uno spostamento e un o per cifra. Se il tuo input non è sano, beh, è lì che diventa brutto, vero? Fare la conversione superveloce non è difficile. Farlo bene in tutte le circostanze è la sfida.
Quindi diamo per scontato che il vostro ingresso è sano di mente, poi il cuore della vostra conversione è questo:
unsigned long PowerOfTwoFromString(char *input, int shift)
{
unsigned long val = 0;
char upperLimit = 'a' + (1 << shift)
while (*input) {
char c = tolower(*input++);
unsigned long digit = (c > 'a' && c < upperLimit) ? c - 'a' + 10 : c - '0';
val = (val << shift) | digit;
}
return val;
}
#define UlongFromBinaryString(str) PowerOfTwoFromString(str, 1)
#define UlongFromHexString(str) PowerOfTwoFromString(str, 4)
Vedere quanto facile che è? E fallirà su input non sani. La maggior parte del tuo lavoro sta andando a rendere il tuo input sensato, non le prestazioni.
Ora, questo codice sfrutta la potenza di due spostamenti. È facile estendere alla base 4, alla base 8, alla base 32, ecc. Non funzionerà sulla non potenza di due basi. Per quelli, la tua matematica deve cambiare. Otterrete
val = (val * base) + digit
che è concettualmente lo stesso per questo insieme di operazioni. La moltiplicazione per base sarà equivalente al turno. Quindi sarei più propenso a usare una routine generale. E disinfettare il codice mentre si disinfettano gli input. E a quel punto, strtoul è probabilmente la soluzione migliore. Ecco un collegamento a a version di strtoul. Quasi tutto il lavoro sta affrontando le condizioni marginali - questo dovrebbe indurvi a capire dove le energie dovrebbero essere focalizzate: codice corretto e resiliente. Il risparmio per l'utilizzo dei bit shift sarà minimo rispetto ai risparmi di say, non andando a crash su input errati.
Sei i primi due nomi di funzione sono estremamente fuorvianti Non si sta restituendo una rappresentazione decimale Si sta restituendo una rappresentazione interna senza segno, con una definizione interna non definita, opaca (a meno che non si definisca un'implementazione) –
Cosa proporresti i nomi delle funzioni? –
Binary2Int e Hex2Int hanno molto più senso Ovviamente queste funzioni non sono necessarie con strtol nella libreria C. – jmucchiello