Десятичное в шестнадцатеричное преобразование (C) не работает для больших чисел

Я делаю C-программу для преобразования десятичного числа в шестнадцатеричное. Моя программа, кажется, работает нормально для меньших чисел, таких как 314156 хранится в длинном int, но больших числах, таких как 11806310474565 или же 8526495043095935640 всегда возвращайся назад 0x7FFFFFFF, Как я могу иметь дело или хранить номера больше, чем 2147483647 / 2^32, Я пытался использовать long long а также unsigned long long, но они не работают должным образом с моим кодом.

код:

#include <stdio.h>
#include <stdlib.h>
int main( int argc, char* argv[] ){
    if(argc != 2 ){
        printf("Usage: %s requires one parameter\n", argv [0]);
        return 1;
    }

    unsigned long long decimal = atoi(argv[1]);
    int count = 0, count2 = 0, value = decimal;
    char hex[100];
    for( ; value!=0 ; value/=10 )
        count++;
    unsigned long long q = decimal;
    int i = 0, r = 0;
    while( q != 0){
        q = decimal/16;
        r = decimal%16; 
        printf("%*llu = %*llu * 16 + %*d (%X)\n", count, decimal, count, q, 3, r, r);
        hex[i++] = r<10 ? r+48 : r+55;
        decimal = q;
    }
    printf("0x");
    for(i-- ; i>=0; i--){
        printf("%c",hex[i]);
    }
    printf("\n");
    return 0;
}

я использую gcc в качестве компилятора.

3 ответа

Решение

Ты хочешь atoll()не atoi(), Прочитайте документацию.

(Раскрытие: я перестал читать ваш код на atoi.)

Преобразовать строку в unsigned long long с strtoull(), @ BLUEPIXY. atoll() не удается, когда результат должен быть> LLONG_MAX,

unsigned long long decimal = strtoull(argv[1], (char **)NULL, 10);

Изменить тип

unsigned long long decimal = ...;
// int  value = decimal;
unsigned long long  value = decimal;

Код имеет проблемы с вводом "0", Это просто печатает "0x"

+ Изменить

while( q != 0){
  ...
}

// to 

do {
  ...
} while( q != 0);

-

Для наглядности рекомендую

// hex[i++] = r<10 ? r+48 : r+55;
hex[i++] = r<10 ? r+'0' : r+'A'-10;
// or 
hex[i++] = "0123456789ABCDEF"[r];

Я пытался использовать long long и unsigned long long, но они не работают должным образом с моим кодом.

Они требуют другого набора функций. Если вы используете atoi разобрать очень большое число, вы получите MAX_INT значение вместо, объясняя 0x7FFFFFFF выход.

Вам нужно заменить функцию на atoll:

unsigned long long decimal = atoll(argv[1]);

Примечание: здесь используются "магические числа"

hex[i++] = r<10 ? r+48 : r+55;

не идеально. Лучше написать

hex[i++] = r<10 ? r+'0' : r+'A'-10;

или даже

hex[i++] = "0123456789ABCDEF"[r];
Другие вопросы по тегам