unsigned long and atoi in C

Code:

char temp[] = "1010000001010011";
printf("%s\n", temp);
unsigned long num = atoi(temp);
printf("%lu\n", num);

Output:

1010000001010011
4081617243

Why is num not 41043?

3 Answers

  1. Jesse- Reply

    2019-11-14

    atoi("1010000001010011"); attempts to convert the text as a sequence of decimal characters to an int. If int was wide enough, it would take on the decimal value of 1,010,000,001,010,011. Not surprisingly, that value is outside OP's int range, so the result is undefined behavior or UB.

    To convert the string as if it was binary characters, use strtol() or strtoul()

    char temp[] = "1010000001010011";
    char *endptr;
    int base = 2;
    unsigned long ulnum = strtoul(temp, &endptr, base);
    if (endptr == temp) puts("No conversion");
    else printf("%lu\n", ulnum);  // 41043
    
  2. Jim- Reply

    2019-11-14

    atoi returns an int value. The decimal number 1010000001010011 which is hex 39696F348895B does not fit a 32-bit variable and was truncated to hex F348895B which is the signed decimal value -213350053. However it is undefined behaviour to assign that value to unsigned long, although the compiler produced code that does assign that bit pattern, which as unsigned long happened to be 4081617243.

    Many thanks to @AnT and to @chux

  3. Jimmy- Reply

    2019-11-14

    Beacouse atoi() converts the string into an integer, does not convert from binary. For example the code

    char str[]="123";
    printf("%d",atoi(str));
    

    will print 123 as an integer

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>