[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

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

Oliver Graeser

9/25/2008 1:45:00 PM

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
15 Answers

Captain Trips

9/25/2008 1:51:00 PM

0

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/vari...

Carlos Caneja

9/25/2008 1:59:00 PM

0

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
> 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

1 is an int, so when you shift it left by more than 32 you wrap around. 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;
for (i=0; i<64; i++){
long long int k = ONE << i;
cout<<i<<"\t"<<k<<"\t"<<sizeof(k)<<"\n";
}

--
Al Dunstan, Software Engineer
OptiMetrics, Inc.
3115 Professional Drive
Ann Arbor, MI 48104-5131

jellybean stonerfish

9/25/2008 2:02:00 PM

0

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?

Victor Bazarov

9/25/2008 2:02:00 PM

0

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";
> }
>
>
> 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

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Richard Herring

9/25/2008 4:41:00 PM

0

In message <vd2dnRWiHbWCBEbVnZ2dnUVZ_tfinZ2d@speakeasy.net>, A. W.
Dunstan <no@spam.thanks> 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

blargg.h4g

9/25/2008 4:55:00 PM

0

In article <gbg4l9$r2c$1@ijustice.itsc.cuhk.edu.hk>, Oliver Graeser
<graeser@phy.cuhk.edu.hk> wrote:

> I need a >49 bit integer type. tried sizeof(long long), says 8. 8 byte =
> 64 bit right?

long long isn't part of C++. Since you're relying on compiler extensions,
you might as well use int64_t from <stdint.h> if you want a 64-bit
integer, or int_least64_t if 64 bits or greater is acceptable.

Victor Bazarov

9/25/2008 5:12:00 PM

0

Richard Herring wrote:
> In message <vd2dnRWiHbWCBEbVnZ2dnUVZ_tfinZ2d@speakeasy.net>, A. W.
> Dunstan <no@spam.thanks> writes
> [..]
>> 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'.

That actually doesn't matter. It could be

const long long int ONE = 1;

or

const long long int ONE = '\1';

the conversion should still yield a suitable value in 'ONE'.

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

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Juha Nieminen

9/25/2008 5:45:00 PM

0

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.

James Kanze

9/25/2008 8:45:00 PM

0

On Sep 25, 6:41 pm, Richard Herring <junk@[127.0.0.1]> wrote:
> In message <vd2dnRWiHbWCBEbVnZ2dnUVZ_tfin...@speakeasy.net>, A. W.
> Dunstan <n...@spam.thanks> 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:james.kanze@gmail.com
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

9/25/2008 8:48:00 PM

0

On Sep 25, 7:44 pm, Juha Nieminen <nos...@thanks.invalid> 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:james.kanze@gmail.com
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