Why is long long int not as long as promised??

Discussion in 'C++' started by Oliver Graeser, Sep 25, 2008.

  1. I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    64 bit right? but when I try to assign a value with more than 32 bit,
    it fails. To illustrate:

    for (i=0; i<64; i++){
    long long int k = 1<<i;

    cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    }


    results in

    1 2 8
    2 4 8
    3 8 8
    4 16 8
    5 32 8
    6 64 8
    7 128 8
    8 256 8
    9 512 8
    10 1024 8
    11 2048 8
    12 4096 8
    13 8192 8
    14 16384 8
    15 32768 8
    16 65536 8
    17 131072 8
    18 262144 8
    19 524288 8
    20 1048576 8
    21 2097152 8
    22 4194304 8
    23 8388608 8
    24 16777216 8
    25 33554432 8
    26 67108864 8
    27 134217728 8
    28 268435456 8
    29 536870912 8
    30 1073741824 8
    31 -2147483648 8
    32 1 8
    33 2 8
    34 4 8
    35 8 8
    36 16 8
    ......

    and so on.

    I'm beyond confused - can anyone here help me out? Machine is a Core 2
    Duo Macbook Pro with OSX10.5, gcc, Xcode.

    Thanks

    Oliver
    Oliver Graeser, Sep 25, 2008
    #1
    1. Advertising

  2. Oliver Graeser wrote:
    > I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    > 64 bit right? but when I try to assign a value with more than 32 bit,
    > it fails. To illustrate:
    >
    > for (i=0; i<64; i++){
    > long long int k = 1<<i;

    unsinged long int k = 1<<i; // use this
    >
    > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > }


    That happens because you have only half of the numbers for positive, the
    other half is used for negatives.

    Look here: http://www.cplusplus.com/doc/tutorial/variables.html
    Captain Trips, Sep 25, 2008
    #2
    1. Advertising

  3. On Thu, 25 Sep 2008 21:45:13 +0800, Oliver Graeser wrote:

    > I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    > 64 bit right? but when I try to assign a value with more than 32 bit,
    > it fails. To illustrate:
    >


    Maybe your 64 bit "int long long" holds positive and negative numbers.
    Is there an "unsigned" type you can use?
    jellybean stonerfish, Sep 25, 2008
    #3
  4. In message <>, A. W.
    Dunstan <> writes
    >Oliver Graeser wrote:
    >
    >> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    >> 64 bit right? but when I try to assign a value with more than 32 bit,
    >> it fails. To illustrate:
    >>
    >> for (i=0; i<64; i++){
    >> long long int k = 1<<i;
    >>
    >> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >> }
    >>
    >>
    >> results in
    >>
    >> 1 2 8

    ....
    >> 30 1073741824 8
    >> 31 -2147483648 8
    >> 32 1 8
    >> 33 2 8
    >> 34 4 8
    >> 35 8 8
    >> 36 16 8
    >> .....
    >>
    >> and so on.
    >>
    >> I'm beyond confused - can anyone here help me out? Machine is a Core 2
    >> Duo Macbook Pro with OSX10.5, gcc, Xcode.
    >>

    >
    >1 is an int, so when you shift it left by more than 32 you wrap around.


    Worse. When you shift it left by 32 or more, you get UB.

    (assuming 'int' is 32 bits on this machine.)

    5.8/1:
    "The behavior is undefined if the right operand is negative, or
    greater than or equal to the length in bits of the promoted left
    operand."

    > The
    >(int) result fits nicely into a 'long long', so the compiler has no reason
    >to complain. Try this:
    >
    >const long long int ONE=1L;


    That would be a 'long' literal, not 'long long'.

    >for (i=0; i<64; i++){
    > long long int k = ONE << i;
    > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >}
    >


    --
    Richard Herring
    Richard Herring, Sep 25, 2008
    #4
  5. Richard Herring wrote:
    >> 1 is an int, so when you shift it left by more than 32 you wrap around.

    >
    > Worse. When you shift it left by 32 or more, you get UB.
    >
    > (assuming 'int' is 32 bits on this machine.)
    >
    > 5.8/1:
    > "The behavior is undefined if the right operand is negative, or
    > greater than or equal to the length in bits of the promoted left operand."


    That's actually something which should be taken seriously. I remember
    back when I was developing on some UltraSparc architecture that if you
    shifted an integer by more bits than there was in the integer, the
    result would be, IIRC, the original value of that integer (rather than
    zero, like AFAIK happens with intel CPUs). In other words, if the amount
    of shift was invalid, the UltraSparc would simply not execute it
    (leaving the original value of the integer intact). This can come as a
    surprise to many.
    Juha Nieminen, Sep 25, 2008
    #5
  6. Oliver Graeser

    James Kanze Guest

    On Sep 25, 6:41 pm, Richard Herring <junk@[127.0.0.1]> wrote:
    > In message <>, A. W.
    > Dunstan <> writes
    > >Oliver Graeser wrote:


    > >> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    > >> 64 bit right? but when I try to assign a value with more than 32 bit,
    > >> it fails. To illustrate:


    > >> for (i=0; i<64; i++){
    > >> long long int k = 1<<i;


    > >> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > >> }


    > >> results in


    > >> 1 2 8

    > ...
    > >> 30 1073741824 8
    > >> 31 -2147483648 8
    > >> 32 1 8
    > >> 33 2 8
    > >> 34 4 8
    > >> 35 8 8
    > >> 36 16 8
    > >> .....


    > >> and so on.


    > >> I'm beyond confused - can anyone here help me out? Machine
    > >> is a Core 2 Duo Macbook Pro with OSX10.5, gcc, Xcode.


    > >1 is an int, so when you shift it left by more than 32 you
    > >wrap around.


    > Worse. When you shift it left by 32 or more, you get UB.


    And it certainly doesn't wrap.

    (But am I the only one who absolutely refuses to use shift
    operators on signed types.)

    > (assuming 'int' is 32 bits on this machine.)


    > 5.8/1:
    > "The behavior is undefined if the right operand is negative, or
    > greater than or equal to the length in bits of the promoted left
    > operand."


    > > The
    > >(int) result fits nicely into a 'long long', so the compiler has no reason
    > >to complain. Try this:


    > >const long long int ONE=1L;


    > That would be a 'long' literal, not 'long long'.


    But ONE would be an integral constant of type long long.

    > >for (i=0; i<64; i++){
    > > long long int k = ONE << i;
    > > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > >}


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Sep 25, 2008
    #6
  7. Oliver Graeser

    James Kanze Guest

    On Sep 25, 7:44 pm, Juha Nieminen <> wrote:
    > Richard Herring wrote:
    > >> 1 is an int, so when you shift it left by more than 32 you wrap around..


    > > Worse. When you shift it left by 32 or more, you get UB.


    > > (assuming 'int' is 32 bits on this machine.)


    > > 5.8/1:
    > > "The behavior is undefined if the right operand is negative, or
    > > greater than or equal to the length in bits of the promoted left operand."


    > That's actually something which should be taken seriously. I
    > remember back when I was developing on some UltraSparc
    > architecture that if you shifted an integer by more bits than
    > there was in the integer, the result would be, IIRC, the
    > original value of that integer (rather than zero, like AFAIK
    > happens with intel CPUs). In other words, if the amount of
    > shift was invalid, the UltraSparc would simply not execute it
    > (leaving the original value of the integer intact). This can
    > come as a surprise to many.


    I think that on a lot of architectures, i << n will actually
    execute as i << (n % B), where B is the number of bits in i. So
    that on a 32 bit machine, i << 32 shifts 0, i << 33 shifts 1,
    etc.

    Of course, if the shift count is a constant, the compiler should
    warn.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Sep 25, 2008
    #7
  8. Oliver Graeser

    farseerfc Guest

    that is because i and 1 is not long long, and therefore the result of 1<<i
    is not long long, not enough to hold a long long value.
    just try this:

    long long int i,one=1;
    for (i=0; i<64; i++){
    long long int k = one<<i;
    cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    }


    "Oliver Graeser" <> 写入消æ¯
    news:gbg4l9$r2c$...
    > I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    > 64 bit right? but when I try to assign a value with more than 32 bit, it
    > fails. To illustrate:
    >
    > for (i=0; i<64; i++){
    > long long int k = 1<<i;
    >
    > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > }
    >
    > results in
    >
    > 1 2 8
    > 2 4 8
    > 3 8 8
    > 4 16 8
    > 5 32 8
    > 6 64 8
    > 7 128 8
    > 8 256 8
    > 9 512 8
    > 10 1024 8
    > 11 2048 8
    > 12 4096 8
    > 13 8192 8
    > 14 16384 8
    > 15 32768 8
    > 16 65536 8
    > 17 131072 8
    > 18 262144 8
    > 19 524288 8
    > 20 1048576 8
    > 21 2097152 8
    > 22 4194304 8
    > 23 8388608 8
    > 24 16777216 8
    > 25 33554432 8
    > 26 67108864 8
    > 27 134217728 8
    > 28 268435456 8
    > 29 536870912 8
    > 30 1073741824 8
    > 31 -2147483648 8
    > 32 1 8
    > 33 2 8
    > 34 4 8
    > 35 8 8
    > 36 16 8
    > .....
    >
    > and so on.
    >
    > I'm beyond confused - can anyone here help me out? Machine is a Core 2 Duo
    > Macbook Pro with OSX10.5, gcc, Xcode.
    >
    > Thanks
    >
    > Oliver
    >
    farseerfc, Sep 26, 2008
    #8
  9. There's no need to use a variable for the constant 1 just to make the
    type long long. You can also use a suffix (ll for long long):

    long long int i;
    for (i=0ll; i<64ll; i++){
    long long int k = 1ll << i;
    cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    }

    ----- Original Message -----
    From: farseerfc
    Date: 26.09.2008 09:26
    > that is because i and 1 is not long long, and therefore the result of 1<<i
    > is not long long, not enough to hold a long long value.
    > just try this:
    >
    > long long int i,one=1;
    > for (i=0; i<64; i++){
    > long long int k = one<<i;
    > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > }
    >
    >
    > "Oliver Graeser" <> 写入消æ¯
    > news:gbg4l9$r2c$...
    >> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte
    >> = 64 bit right? but when I try to assign a value with more than 32
    >> bit, it fails. To illustrate:
    >>
    >> for (i=0; i<64; i++){
    >> long long int k = 1<<i;
    >>
    >> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >> }
    >>
    >> results in
    >>
    >> 1 2 8
    >> 2 4 8
    >> 3 8 8
    >> 4 16 8
    >> 5 32 8
    >> 6 64 8
    >> 7 128 8
    >> 8 256 8
    >> 9 512 8
    >> 10 1024 8
    >> 11 2048 8
    >> 12 4096 8
    >> 13 8192 8
    >> 14 16384 8
    >> 15 32768 8
    >> 16 65536 8
    >> 17 131072 8
    >> 18 262144 8
    >> 19 524288 8
    >> 20 1048576 8
    >> 21 2097152 8
    >> 22 4194304 8
    >> 23 8388608 8
    >> 24 16777216 8
    >> 25 33554432 8
    >> 26 67108864 8
    >> 27 134217728 8
    >> 28 268435456 8
    >> 29 536870912 8
    >> 30 1073741824 8
    >> 31 -2147483648 8
    >> 32 1 8
    >> 33 2 8
    >> 34 4 8
    >> 35 8 8
    >> 36 16 8
    >> .....
    >>
    >> and so on.
    >>
    >> I'm beyond confused - can anyone here help me out? Machine is a Core 2
    >> Duo Macbook Pro with OSX10.5, gcc, Xcode.
    >>
    >> Thanks
    >>
    >> Oliver
    >>
    Stefan Rondinelli, Sep 26, 2008
    #9
  10. Oliver Graeser

    farseerfc Guest

    ;-p, thank you telling me the suffix from
    but 1ll seems too much like 111, 1LL should be better

    and is the suffix of unsigned long long int ULL? maybe we could write 0ULL
    to mean NULL, how beauty C++ is!

    Just a joke~

    "Stefan Rondinelli" <> wrote
    news:9e46$48dc9b17$d437c637$...
    > There's no need to use a variable for the constant 1 just to make the type
    > long long. You can also use a suffix (ll for long long):
    >
    > long long int i;
    > for (i=0ll; i<64ll; i++){
    > long long int k = 1ll << i;
    > cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    > }
    >
    > ----- Original Message -----
    > From: farseerfc
    > Date: 26.09.2008 09:26
    >> that is because i and 1 is not long long, and therefore the result of
    >> 1<<i
    >> is not long long, not enough to hold a long long value.
    >> just try this:
    >>
    >> long long int i,one=1;
    >> for (i=0; i<64; i++){
    >> long long int k = one<<i;
    >> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >> }
    >>
    >>
    >> "Oliver Graeser" <> 写入消æ¯
    >> news:gbg4l9$r2c$...
    >>> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
    >>> 64 bit right? but when I try to assign a value with more than 32 bit, it
    >>> fails. To illustrate:
    >>>
    >>> for (i=0; i<64; i++){
    >>> long long int k = 1<<i;
    >>>
    >>> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >>> }
    >>>
    >>> results in
    >>>
    >>> 1 2 8
    >>> 2 4 8
    >>> 3 8 8
    >>> 4 16 8
    >>> 5 32 8
    >>> 6 64 8
    >>> 7 128 8
    >>> 8 256 8
    >>> 9 512 8
    >>> 10 1024 8
    >>> 11 2048 8
    >>> 12 4096 8
    >>> 13 8192 8
    >>> 14 16384 8
    >>> 15 32768 8
    >>> 16 65536 8
    >>> 17 131072 8
    >>> 18 262144 8
    >>> 19 524288 8
    >>> 20 1048576 8
    >>> 21 2097152 8
    >>> 22 4194304 8
    >>> 23 8388608 8
    >>> 24 16777216 8
    >>> 25 33554432 8
    >>> 26 67108864 8
    >>> 27 134217728 8
    >>> 28 268435456 8
    >>> 29 536870912 8
    >>> 30 1073741824 8
    >>> 31 -2147483648 8
    >>> 32 1 8
    >>> 33 2 8
    >>> 34 4 8
    >>> 35 8 8
    >>> 36 16 8
    >>> .....
    >>>
    >>> and so on.
    >>>
    >>> I'm beyond confused - can anyone here help me out? Machine is a Core 2
    >>> Duo Macbook Pro with OSX10.5, gcc, Xcode.
    >>>
    >>> Thanks
    >>>
    >>> Oliver
    >>>

    >
    farseerfc, Sep 26, 2008
    #10
  11. Victor Bazarov wrote:
    > Oliver Graeser wrote:
    >> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte
    >> = 64 bit right? but when I try to assign a value with more than 32
    >> bit, it fails. To illustrate:
    >>
    >> for (i=0; i<64; i++){
    >> long long int k = 1<<i;

    >
    > Try changing this to
    >
    > long long int k = 1LL << i; // note the suffix after '1'.
    >
    > You were shifting a simple int (1 is of type int), and its range is more
    > limited than that of 'long long'.
    >
    >> cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
    >> }


    Indeed this works. Thanks a lot, wasn't aware that directly typed
    numbers are always int. Also tried k=100000000000000 but it wouldn't
    even compile.
    Oliver Graeser, Sep 26, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Crimarc

    What C++ has promised you ?

    Crimarc, Mar 6, 2005, in forum: C++
    Replies:
    1
    Views:
    321
    Victor Bazarov
    Mar 6, 2005
  2. Schnoffos
    Replies:
    2
    Views:
    1,198
    Martien Verbruggen
    Jun 27, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,615
    Old Wolf
    Jan 20, 2004
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  5. Gandalf

    As I promised couple of day a go

    Gandalf, May 30, 2008, in forum: Python
    Replies:
    0
    Views:
    365
    Gandalf
    May 30, 2008
Loading...

Share This Page