19

I checked the document that long= int64 has range more than 900,000,000,000,000

Here is my code:

int r = 99;
long test1 = r*r*r*r*r;

at runtime it gives me 919,965,907 instead of the correct 9,509,900,499.

another test

long test2 = 99*99*99*99*99;

It refuses to compile, saying integer overflow.

But if i do this

long test3 = 10100200300;

This works fine.

5 Answers 5

48

The problem is that the literal "99" is being treated as an int. If you add "L" it will treat it as a long. To fix your compilation problem:

long test2 = 99L * 99L * 99L * 99L * 99L;

And to fix the "incorrect result" caused by integer overflow:

long r = 99;
long test1 = r * r * r * r * r;

The key point is that the expression to the right of the "=" is evaluated before the assignment to long r is done.

There are other literal suffixes you might be interested in:

Type    Suffix    Example
uint    U or u    100U
long    L or l    100L
ulong   UL or ul  100UL
float   F or f    123.45F
decimal M or m    123.45M

@m.edmonson, regarding your question about why it comes out to 919965907. What's happening, is that the value is "wrapping" around int.MaxValue. You can see this with a little test program:

int i = 99; // 99
i *= 99;    // 9801
i *= 99;    // 970299
i *= 99;    // 96059601
i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
            //                      which is (9509900499 % int.MaxValue)

long k = 9509900499 % int.MaxValue;

What is meant by "wrapping around"? When you exceed int.MaxValue by 1, the value "goes back" to int.MinValue.

int j = int.MaxValue;
j++;

bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"

This is a bit simplistic; if you search for "integer overflow" you will get a better explanation. It's worth understanding how integers (and other numeric types) are represented with 32 bits:

http://en.wikipedia.org/wiki/Signed_number_representations

Sign up to request clarification or add additional context in comments.

5 Comments

Excellent answer - can you explain why he gets a different result between long and integer multiplication?
Can you clarify what you mean by wrapping? And what thats got to do with modulus % ?
I believe you only need one 99L, the rest will upcast.
s/upcast/undergo integral promotion/
Int values are not wrapped around "int.MaxValue" and formula "9509900499 % int.MaxValue" is not correct. Correct formula is: "(9509900499 + int.MaxValue + 1) % ((long)int.MaxValue - int.MinValue + 1) - int.MaxValue - 1"
5

It's using integer multiplication :

long r = 99;
long test1 = r*r*r*r*r;

Comments

4

As the other have said, but:

long test2 = 99L * 99 * 99 * 99 * 99;

This will give you the correct result with less L around :-)

This happens because the first 99L is a long, so all the multiplications are done in the long "field" and all the other integers are upcasted to long before the multiplication (clearly the multiplication is always between 2 numbers and it's from left to right, so it's like (((99L * 99) * 99) * 99) * 99 and each "partial" result is a long and causes the next operand to be converted to long.)

Comments

3

Your second test fails because each 99 is an integer; replace it with the following and it compiles.

long test2 = 99L * 99L * 99L * 99L * 99L;

See the MSDN Long Documentation for details.

Comments

1

The compiler is looking at 99 as integers, even though the final result will be long.

This will work.

long test2 = 99L*99L*99L*99L*99L;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.