Десятичное в шестнадцатеричное преобразование (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];