简体   繁体   中英

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.

循环的前一个图表

Sample Java project on codingground.com is here .

What am I missing?

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;

You're doing int math here:

long result = i * 184528125;

...because i is an int , and numeric literals are int s 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.

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

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;

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

2 63 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 2 63 -1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM