Thread: number of bits supported for int on my machine

  1. #1
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95

    number of bits supported for int on my machine

    I am doing a problem that asks for the number of bits allocated to an integer on my machine. The problem states given the fact that ~0 produces an integer with all zeros, write a program that would indicate how many bits are allocated to an integer. So I wrote this

    Code:
    #include <stdio.h>
    int main (void)
    {
    int i;
    i = 0;
    printf ("Here is  ----%o\n", ~i);
    }
    Here is the output:

    Code:
    $ 3
    Here is  ----37777777777
    Given that I am printing this in octal I believe I am looking at 32 bits. Right? I do realize these are two different things, but I am using Win10 and expected 64bits. I even switched compilers to the 64bit version of MinGw but the result is the same. I guess I am trying to figure out which of the following decides the size of the memory allocated to the integer; is it the compiler, OS architecture, of C language?

  2. #2
    Tweaking master Aslaville's Avatar
    Join Date
    Sep 2012
    Location
    Rogueport
    Posts
    528
    Quote Originally Posted by zolfaghar View Post
    I am doing a problem that asks for the number of bits allocated to an integer on my machine.
    Talking about integer is ambiguous. We can have 'short' integer, integer, long integer, long long integer.

    I think you're talking about long integer which is typically 64-bits on 64 bit machines.

    Also, make sure you're formatting correctly when printing. If you expect a long integer you have to format a long integer otherwise it will be truncated.

  3. #3
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    It changed when I declared a variable as long long

    Code:
    $ less 3.c
    //This program shows how many bits are allocated to an integer. Note however, you are compiling this
    // with a 32bit compiler. MinGw-64 might very well give a different answer.
    #include <stdio.h>
    int main (void)
    {
    int i;
    i = 0;
    long int j;
    long long int k;
    printf ("Here is number ----%lo\n", ~i);
    printf ("Here is number ----%llo\n", ~i);
    printf ("Here is number ----%llu\n", ~i);
    j = 0;
    printf ("Here is number ----%lo\n", ~j);
    printf ("Here is number ----%llo\n", ~j);
    printf ("Here is number ----%llu\n", ~j);
    k =0;
    printf ("Here is number ----%lo\n", ~k);
    printf ("Here is number ----%llo\n", ~k);
    printf ("Here is number ----%llu\n", ~k);
    }
    $ 3
    Here is number ----37777777777
    Here is number ----37777777777
    Here is number ----4294967295
    Here is number ----37777777777
    Here is number ----37777777777
    Here is number ----4294967295
    Here is number ----37777777777
    Here is number ----1777777777777777777777
    Here is number ----18446744073709551615
    Last edited by zolfaghar; 06-08-2016 at 11:10 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by zolfaghar
    The problem states given the fact that ~0 produces an integer with all zeros, write a program that would indicate how many bits are allocated to an integer.
    ~0 results in an integer with all the bits set, not unset. A catch is that the interpretation of the result is different depending on whether the integer is unsigned, signed in two's complement, signed in one's complement, or signed in sign and magnitude representation.

    Quote Originally Posted by zolfaghar
    It changed when I declared a variable as long long
    Sure, but the program that you wrote does not correctly match the format specifiers to their corresponding arguments in many cases. For example, gcc 4.8.4 rightly warns:
    Code:
    test.c: In function ‘main’:
    test.c:8:1: warning: format ‘%lo’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%lo\n", ~i);
     ^
    test.c:9:1: warning: format ‘%llo’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%llo\n", ~i);
     ^
    test.c:10:1: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%llu\n", ~i);
     ^
    test.c:13:1: warning: format ‘%llo’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘long int’ [-Wformat=]
     printf ("Here is number ----%llo\n", ~j);
     ^
    test.c:14:1: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘long int’ [-Wformat=]
     printf ("Here is number ----%llu\n", ~j);
     ^
    test.c:16:1: warning: format ‘%lo’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long int’ [-Wformat=]
     printf ("Here is number ----%lo\n", ~k);
     ^
    These mismatches technically lead to undefined behaviour. What you can do is to either change the format specifier to match the type of the argument, or cast the arguments so that the type matches the format specifier.
    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

  5. #5
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Quote Originally Posted by laserlight View Post
    ~0 results in an integer with all the bits set, not unset. A catch is that the interpretation of the result is different depending on whether the integer is unsigned, signed in two's complement, signed in one's complement, or signed in sign and magnitude representation.


    Sure, but the program that you wrote does not correctly match the format specifiers to their corresponding arguments in many cases. For example, gcc 4.8.4 rightly warns:
    Code:
    test.c: In function ‘main’:
    test.c:8:1: warning: format ‘%lo’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%lo\n", ~i);
     ^
    test.c:9:1: warning: format ‘%llo’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%llo\n", ~i);
     ^
    test.c:10:1: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf ("Here is number ----%llu\n", ~i);
     ^
    test.c:13:1: warning: format ‘%llo’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘long int’ [-Wformat=]
     printf ("Here is number ----%llo\n", ~j);
     ^
    test.c:14:1: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘long int’ [-Wformat=]
     printf ("Here is number ----%llu\n", ~j);
     ^
    test.c:16:1: warning: format ‘%lo’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long int’ [-Wformat=]
     printf ("Here is number ----%lo\n", ~k);
     ^
    These mismatches technically lead to undefined behaviour. What you can do is to either change the format specifier to match the type of the argument, or cast the arguments so that the type matches the format specifier.
    Thanks. I'll fix that.

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by Aslaville View Post
    I think you're talking about long integer which is typically 64-bits on 64 bit machines.
    On 64-bit Windows, the "long" type is 32 bits for backward compatibility with a bunch of poorly-written software that assumes "LONG" and "long" are the same type. Granted, Windows APIs are poorly designed for using a 32-bit "LONG" type in the first place.

    Virtually every other 64-bit OS has a 64-bit long type because they don't have such backward-compatibility issues.
    Last edited by christop; 06-09-2016 at 09:14 AM.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I'm not sure how every bit set is supposed to help? Maybe looking for something like this?
    Code:
        int c;
        unsigned int v = ~0;
        for (c = 0; v > 0; ++c, v &= v - 1) /* void */;
    c contains the number of bits.

  8. #8
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    I don't know why you're using octal. Hex is more common.
    Code:
    #include <stdio.h>
    
    int main(void) {
        unsigned             i = 0;
        long unsigned       li = 0;
        long long unsigned lli = 0;
    
        printf("          unsigned: %16x\n",     ~i);
        printf("     long unsigned: %16lx\n",   ~li);
        printf("long long unsigned: %16llx\n", ~lli);
    
        return 0;
    }
    
    /* Ouptut:
              unsigned:         ffffffff
         long unsigned: ffffffffffffffff
    long long unsigned: ffffffffffffffff
    */

  9. #9
    Tweaking master Aslaville's Avatar
    Join Date
    Sep 2012
    Location
    Rogueport
    Posts
    528
    Quote Originally Posted by whiteflags View Post
    I'm not sure how every bit set is supposed to help? Maybe looking for something like this?
    Code:
        int c;
        unsigned int v = ~0;
        for (c = 0; v > 0; ++c, v &= v - 1) /* void */;
    c contains the number of bits.
    Well, in my case, I was wondering why we are not using 'sizeof' ? Am I missing something or should 'sizeof' be enough ?

    Code:
    #include <stdio.h>
    
    
    int main (void)
    {
        printf ("Here is  ----%d\n", sizeof(long int) * 8);
    }

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Aslaville
    Well, in my case, I was wondering why we are not using 'sizeof' ? Am I missing something or should 'sizeof' be enough ?
    No, sizeof is not enough. You need CHAR_BIT as well. While you can multiply by 8 as per your example, that magic number is not guaranteed to be the number of bits per byte in a given C implementation.

    Anyway, while the approach you have in mind is sensible, it ignores the premise: "The problem states given the fact that ~0 produces an integer with all zeros" (where "zeros" is a misprint for "ones").
    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

  11. #11
    Registered User
    Join Date
    Dec 2011
    Location
    Namib desert
    Posts
    94
    Code:
    #include <stdio.h>
    
    // gcc tst.c -o tst
    
    int main()
    {
        int i;
        int Sj;
        unsigned int Uj;
    
    
        for(Sj=1, i=0; Sj != 0; Sj <<= 1,i++);
    
        printf("Number of iterations/bits = %d for a signed int\n", i);
    
    
    
        for(Uj=1, i=0; Uj !=0; Uj <<= 1,i++);
    
        printf("Number of iterations/bits = %d for an unsigned int\n", i);
    
    }

  12. #12
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Ah. Thanks. This is what I was wondering about; why it is not 64. Thanks.

  13. #13
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Quote Originally Posted by christop View Post
    On 64-bit Windows, the "long" type is 32 bits for backward compatibility with a bunch of poorly-written software that assumes "LONG" and "long" are the same type. Granted, Windows APIs are poorly designed for using a 32-bit "LONG" type in the first place.

    Virtually every other 64-bit OS has a 64-bit long type because they don't have such backward-compatibility issues.
    This was my question; thanks for the answer. I was wondering why even long ints were not allocated 64 bits.

  14. #14
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Quote Originally Posted by whiteflags View Post
    I'm not sure how every bit set is supposed to help? Maybe looking for something like this?
    Code:
        int c;
        unsigned int v = ~0;
        for (c = 0; v > 0; ++c, v &= v - 1) /* void */;
    c contains the number of bits.
    I should have provided more context. As you may know I switched books, and now I am following "Programming in C" by Stephen Kochan. He mentioned in chapter 11, that different machines allocate different number of bits to an integer, and not to make any assumptions on the number of bits allocated to an unsigned int when attempting one of his problems. I took that, and wanted to understand it even better; that is why I asked the question. I think knowing about these issues and understanding as to why they come up and how to find out about them is important. This is based on my very limited coding skills; I just envision I may run into situations which I need to be aware of such potential mismatches.

    By the way thanks to everyone who told me to switch books.

  15. #15
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    ANSI C defines the following sizes for the various primitive data types.

    char
    minimum signed range: -128 .. 127
    minimum unsigned range: 0 .. 255
    can be larger, but regardless of size, sizeof(char) == 1
    sizeof(unsigned char) == 1

    short
    minimum signed range: -32768 .. 32767
    minimum unsigned range: 0 .. 65535
    can be larger

    long
    minimum signed range: -2147483648 .. 2147483647
    minimum unsigned range: 0 .. 4294967295
    can be larger

    int
    must have, at a miminum, the same range as a short
    can have the same range as a long
    cannot have a range larger than a long
    short <= int, and int <= long, but short < long
    There are a bunch more rules for floats and doubles, but generally, the range of a float is <= the range of a double (for modern machines---float is 4 bytes, double is 8).
    As you see the book, advising you not to make any assumptions on the amount of bits( and as an extension, the capacity) of a type, is wrong. Although many micro-controller implementations aren't even close to standard-conforming...
    Devoted my life to programming...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What to do with odd number of bits?
    By Meiryousa in forum C++ Programming
    Replies: 3
    Last Post: 12-31-2013, 01:51 AM
  2. Number of bits in types
    By TriKri in forum C Programming
    Replies: 7
    Last Post: 12-02-2006, 12:56 PM
  3. Counter the number of 1 bits?
    By gqchynaboy in forum C++ Programming
    Replies: 30
    Last Post: 04-04-2005, 07:07 AM
  4. Number of set bits
    By Roaring_Tiger in forum C Programming
    Replies: 8
    Last Post: 09-22-2004, 09:05 PM
  5. copy some bits into a 8 bits binary number
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 05-29-2002, 10:54 AM

Tags for this Thread