-1

I'm making a C program to convert a decimal into a hexadecimal. My program seems to work fine for smaller numbers like 314156 stored in a long int but larger numbers such as 11806310474565 or 8526495043095935640 always return back 0x7FFFFFFF. How can I deal with or store numbers larger than 2147483647 / 2^32. I've tried using long long and unsigned long long, but those aren't working properly with my code.

code:

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

I'm using gcc as a compiler.

below_avg_st
  • 177
  • 14

3 Answers3

1

You want atoll(), not atoi(). Read the documentation.

(Disclosure: I stopped reading your code at atoi.)

Dúthomhas
  • 4,323
  • 2
  • 11
  • 25
  • Fair enough. I forgot about `atoll()` @Dúthomhas. – below_avg_st Sep 21 '17 at 03:10
  • `atoll()` can certainly fail with input like "18446744073709551615" (2**64 - 1) – chux - Reinstate Monica Sep 21 '17 at 04:12
  • Yes, OP can also use `stroull()` or the like, but at some large number it will fail. If he wishes to process arbitrarily large numbers, he must either get a bignum library or figure out how to do the processing himself. Either way, I do not know his requirements. – Dúthomhas Sep 21 '17 at 16:57
0

I've tried using long long and unsigned long long, but those aren't working properly with my code.

They require a different set of functions. If you use atoi to parse a very large number, you get MAX_INT value instead, explaining 0x7FFFFFFF output.

You need to replace the function by atoll:

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

Note: Using "magic numbers" here

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

is not ideal. It is better to write

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

or even

hex[i++] = "0123456789ABCDEF"[r];
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
0

Convert a string to an unsigned long long with strtoull(). @BLUEPIXY. atoll() fails when the result should be > LLONG_MAX.

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

Change type

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

Code has trouble with input "0". It just prints "0x"

Change

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

// to 

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

--

For clarity, recommend

// hex[i++] = r<10 ? r+48 : r+55;
hex[i++] = r<10 ? r+'0' : r+'A'-10;
// or 
hex[i++] = "0123456789ABCDEF"[r];
chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213