Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I get my integer arithmetic into a long long?

As part of exercise 2-3 in Ritchie and Kernighan’s C programming language, I’ve written a program that converts hexadecimal inputs into decimal outputs. I want it to be able to handle larger numbers, but it seems to be doing integer arithmetic somewhere. When you enter something like "DECAFCAB" it spits out a large negative int. I figured out that I need to add the "LL" suffix to my literals, which I did, but it’s still not working. Any help please? Sorry if this is a dumb question or a typo, but I’ve been at it for an hour and can’t figure it out. 🙁

#include <stdio.h>
#define MAX_LINE 1000 

void getline(char s[])
{
    int i;
    char c;

    for(i = 0; i < MAX_LINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    s[i] = '\0';
    printf("\n%s", s);
}

long long htoi(char s[]) // convert the hex string to dec
{
    long long n = 0;
    int i = 0;

    if(s[i] == '0') // eat optional leading Ox or OX
        ++i;

    if(s[i] == 'x' || s[i] == 'X')
         ++i;

    while(s[i] != '\0')
    {
        if((s[i] >= '0' && s[i] <= '9'))
            n = 16LL * n + (s[i] - '0'); // here is the arithmetic in question
        else if(s[i] >= 'A' && s[i]<= 'F')
            n = 16LL * n + (s[i] - 'A' + 10LL);
        else if(s[i] >= 'a' && s[i] <= 'f')
            n = 16LL * n + (s[i] - 'a' + 10LL);
        else {
                printf("\nError: Encountered a non-hexadecimal format: the '%c' character was unexpected.", s[i]);
                printf("\nHexadecimal numbers can begin with an optional 0x or 0X only, and contain 0-9, A-F, and a-f.\n\n");
                return -1;
             }
        ++i;

    }
    return n;
}

main()
{
    char input[MAX_LINE];
    long long hex_output;

    while(1){
        getline(input);
        hex_output = htoi(input);
        if(hex_output >= 0)
        printf("\nThe value of the hexadecimal %s is %d in decimal.\n\n", input, hex_output);
    }
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You told printf to expect an int when you made the placeholder %d. To make it expect (and therefore read the entirety of a) long long, modify it to %lld.

The reason it looks like a plain int is that with varargs functions like printf, it doesn’t know what the argument sizes are, and the format string is the only way to figure it out. When you say to expect plain int, it reads sizeof(int) bytes from the argument, not sizeof(long long) bytes (it’s not necessarily byte-oriented, but that’s how much data is read), and (on a little endian system with 4 byte int and 8 byte long long) you see (roughly) the result of the argument with the top 4 bytes masked off.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading