JerabekJakub
JerabekJakub

Reputation: 5340

Range of primitive type long in Java

I have found in documentation that range of long is from -2^63 to 2^63-1.

When I run this for cycle I'm unable to get over cca 2 000 000 000.

Log.d(TAG, "Long MAX = " + Long.MAX_VALUE);
for (int i = 1; i < 45; i++) {
    long result = i * 184528125;
    Log.d(TAG, "" + result);
}

Output is "Long MAX = 9223372036854775807" and result values in graph is below.

graph of previous for cycle

Sample Java project on codingground.com is here.

What am I missing?

Upvotes: 3

Views: 1588

Answers (6)

Solution 1:

Use a long literal by appending an L to the end of digits:

long result = i * 184528125L;

Solution 2:

Change the for loop to:

for (long i = 0; i<45; i++){

This will make sure you have at least one long value when doing this calculation:

long result = i * 184528125;//i is now a long

Solution 3:

Cast one of the values as a long:

long result = i * (long)184528125;

Upvotes: 1

Fire Ruler
Fire Ruler

Reputation: 46

long result = i * 184528125;

The statement above is the culprit. By default, numerical values are int. Also you defined i as an int as well.

options:

  1. Define i as long
  2. Add long modifier L to the 184528125

Upvotes: 1

llogiq
llogiq

Reputation: 14541

263 is not divisible by 184528125. The nearest number you can get with your method is 49983556906 * 184528125 = 9223372036694981250.

If you Log.d("" + 0xFFFFFFFFFFFFFFFFL), you will get 263-1

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502246

The problem is this line:

long result = i * 184528125;

The right hand side is evaluated in 32-bit integer arithmetic, because both operands are int. There's then an implicit conversion to long. To fix it, just make the RHS a long constant:

long result = i * 184528125L;

Note that this is similar to the common problem of doing something like:

int x = 1;
double d = x / 2; // d is 0, not 0.5...

Upvotes: 2

Jesper
Jesper

Reputation: 206906

This line is wrong:

long result = i * 184528125;

It multiplies two 32-bit int values. The result will be a 32-bit int (which has overflowed) which is then converted to a 64-bit long.

You want to do 64-bit multiplication instead. Make one of the two operands a long. The easiest way to do that is to use the L suffix on the constant:

long result = i * 184528125L;

Upvotes: 4

T.J. Crowder
T.J. Crowder

Reputation: 1075029

You're doing int math here:

long result = i * 184528125;

...because i is an int, and numeric literals are ints by default. So first i * 184528125 happens, limited to the int range, and then the result (which wraps, as you found) is promoted to long and assigned to result.

Instead, either make i a long or make the numeric literal a long:

long result = i * 184528125L;
// Note -------------------^

Now the multiplication happens with long values, with access to the full long range.

Upvotes: 2

Related Questions