Thread: Right way to show numbers in binary/hex/octal in your opinion?

  1. #1
    Registered User
    Join Date
    Oct 2021
    Posts
    138

    Right way to show numbers in binary/hex/octal in your opinion?

    So I have this function that converts a number to a string and it can return it in any base you want. However, for negative numbers, the result may not be what you expected for bases other than decimal if you have used "printf" or "wirtef". Let's say that we want to convert then number -10 from decimal to hex. There are two possible results (check here: Decimal to Hexadecimal Converter).

    The first one is negate the number and convert it to hex and then add a "-" in front of the number. So the result will be: -a (which is what my function does)

    The second one is what "printf" and "writef" does which is using 2's complement. So in this case, we first convert the number to binary using 2's complement and then we convert this number to hex. In this example, -10 to binary is 1111111111110110 which is fff6 in hex. However, for some reason "printf" and "writef" return fffffff6 so go figure....

    Here are the advantages of these two methods in my humble opinion:

    First method:
    1. Is is what my function does and I would prefer not to change it obviously. Also implementing the other behavior, would need a lot of work (and of course I will have to figure it out, don't know how to do it) and it will make the function much slower.
    2. It is easier on they eyes as it makes it more obvious to understand if the number is signed or not and so what the equivalent is in other systems.

    Second method:
    1. It is probably what people would expect and what makes scientifically more sense as decimal was supposed to be the only base that will make sense for humans to read hence be the only base that has the "-" character.

    Anyway, I don't even know why it will be practical useful to print a number in another system so, what are your thoughts?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by rempas
    In this example, -10 to binary is 1111111111110110 which is fff6 in hex. However, for some reason "printf" and "writef" return fffffff6 so go figure....
    That's because int is presumably 4 bytes and thus 32 bits on your system. The online calculator you used set it as 16 bits instead.

    That would be a general issue if you choose to go with option 2: the representation of the negative integer necessarily depends on how many bits you intend to represent. (That's kind of true for positive integers too, but I guess it is more natural for humans familiar with the Hindu-Arabic numeral system to omit leading zeroes.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    It's kind of a silly question. Do what you want. The %o and %x formats for printf are defined to work only with unsigned integers so they interpret the representation of the signed value as an unsigned value.

    BTW, the correct answer for a negative signed integer 2's complement representation depends on the number of bits of the variable. For 16 bits, -10 is fff6, but for 32 bits (which is what your system uses) it is fffffff6.

    BTW2, there is no such thing as writef.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
     
    void print_unsigned(unsigned n, unsigned b) // b in [2, 36]
    {
        const char *a = "0123456789abcdefghijklmnopqrstuvwxyz";
        if (n >= b) print_unsigned(n / b, b);
        putchar(a[n % b]);
    }
     
    void print_signed(int n, int b) // b in [2, 36]
    {
        if (n < 0) { putchar('-'); n = -n; }
        print_unsigned(n, b);
    }
     
    int main()
    {
        char line[256];
        while (printf(">>> "), fgets(line, sizeof line, stdin) != NULL)
        {
            int n = 0;
            if      (strcmp(line, "min\n")   == 0) n =  INT_MIN;
            else if (strcmp(line, "min+1\n") == 0) n =  INT_MIN + 1;
            else if (strcmp(line, "max\n")   == 0) n =  INT_MAX;
            else if (strcmp(line, "-max\n")  == 0) n = -INT_MAX;
            else
                n = atoi(line);
     
            printf("d: %d\n", n);
     
            for (int b = 2; b <= 36; ++b)
            {
                printf("%2d: ", b);
                print_signed(n,  b);
                putchar('\n');
            }
        }
     
        putchar('\n');
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  4. #4
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by john.c View Post
    It's kind of a silly question. Do what you want. The %o and %x formats for printf are defined to work only with unsigned integers so they interpret the representation of the signed value as an unsigned value.

    BTW, the correct answer for a negative signed integer 2's complement representation depends on the number of bits of the variable. For 16 bits, -10 is fff6, but for 32 bits (which is what your system uses) it is fffffff6.

    BTW2, there is no such thing as writef.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
     
    void print_unsigned(unsigned n, unsigned b) // b in [2, 36]
    {
        const char *a = "0123456789abcdefghijklmnopqrstuvwxyz";
        if (n >= b) print_unsigned(n / b, b);
        putchar(a[n % b]);
    }
     
    void print_signed(int n, int b) // b in [2, 36]
    {
        if (n < 0) { putchar('-'); n = -n; }
        print_unsigned(n, b);
    }
     
    int main()
    {
        char line[256];
        while (printf(">>> "), fgets(line, sizeof line, stdin) != NULL)
        {
            int n = 0;
            if      (strcmp(line, "min\n")   == 0) n =  INT_MIN;
            else if (strcmp(line, "min+1\n") == 0) n =  INT_MIN + 1;
            else if (strcmp(line, "max\n")   == 0) n =  INT_MAX;
            else if (strcmp(line, "-max\n")  == 0) n = -INT_MAX;
            else
                n = atoi(line);
     
            printf("d: %d\n", n);
     
            for (int b = 2; b <= 36; ++b)
            {
                printf("%2d: ", b);
                print_signed(n,  b);
                putchar('\n');
            }
        }
     
        putchar('\n');
        return 0;
    }
    Thanks! I will use the first way in that case as it is both easier (both on code and on the eyes). Also, I posted this message in the D language forums and "writef" is from the standard library of Dlang. So yeah I forgot to remove it here...

  5. #5
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by laserlight View Post
    That's because int is presumably 4 bytes and thus 32 bits on your system. The online calculator you used set it as 16 bits instead.

    That would be a general issue if you choose to go with option 2: the representation of the negative integer necessarily depends on how many bits you intend to represent. (That's kind of true for positive integers too, but I guess it is more natural for humans familiar with the Hindu-Arabic numeral system to omit leading zeroes.)
    Thanks a lot! In this case I think it makes more sense to use the first one then and it is also ready so that's awesome!!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Adding two octal numbers from char[] C language
    By kamilosinio in forum C Programming
    Replies: 4
    Last Post: 04-25-2020, 03:49 AM
  2. Searching octal numbers in string (Text).
    By bran12 in forum C Programming
    Replies: 1
    Last Post: 11-22-2015, 08:04 AM
  3. Replies: 2
    Last Post: 05-08-2015, 07:47 PM
  4. octal numbers
    By firefly in forum C++ Programming
    Replies: 4
    Last Post: 07-13-2005, 06:24 AM
  5. binary/octal/hexadecimal
    By razrektah in forum C++ Programming
    Replies: 2
    Last Post: 09-13-2001, 06:33 PM

Tags for this Thread