简体   繁体   中英

Why can't I print the maximum long value?

I am compiling a Java program using for loop to find out the biggest value of long. However, nothing was printed when I run the program. Why?

Here's my code:

class LongMaxMin {
public static void main(String args[]) {

    long i = 0L;
    long result = 0L;

    for (; ; ) {
        result = i++;
        if (i<0) 
            break;
    }
    System.out.println("The biggest integer:" + result);
  }

Mostly because of time.

A long will have a max of about ~9.22 quintillion. You're starting at zero and incrementing up. That means you need to go through 9 quintillion loops before it wraps over and breaks. I just tried to run 2 billion operations in my javascript console and times out for a couple of minutes before I force quit.

If you sit there and let it run long enough, you'll get your output. Alternatively, start i at something close to the max already, like 9,223,372,036,854,700,000 , and see if it still gives you the same issues. In Java 8, adding underscore to numeric literals is allowed. Initializing i to something like 9_223_372_036_854_700_000L will give you something in a more timely manner.

The max long is significantly high, at 9.223372e+18 . For specifics , 9,223,372,036,854,775,807 is the number in question. This also contributes to that whole "this works, it'll just take WAY too long" theory.

I was curious how long it would take so I wrote a class to do the same thing. Wrote it with a separate thread to update results to the console every 1 second.

"int" results

1,343,211,433   37.4518434691484288634492200 % left

Max Value: 2,147,483,647
Time Taken (seconds): **1.588**

"long" results

1,220,167,357   99.9999999867709190074470400 % left
2,519,937,368   99.9999999726787843108699600 % left
3,881,970,343   99.9999999579115932059510100 % left
5,210,983,861   99.9999999435023997711689800 % left
6,562,562,290   99.9999999288485570811055300 % left
7,853,387,353   99.9999999148534037050721500 % left
9,137,607,100   99.9999999009298653086103000 % left
10,467,975,104  99.9999998865059865071902600 % left
11,813,910,300  99.9999998719133278719112300 % left
13,183,196,499  99.9999998570674971548090400 % left
...it continues on and on...

1,362,032,97 - difference between the 2nd and 3rd values (1 second)
6,771,768,529 seconds - how many seconds it would take to reach long's max value (Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 seconds = 214.73 years (per conversion by google search)

So if my calculations are correct...you'd be dead of old age by the time an average computer calculated the max value of long via incrementing and checking if it's overflowed. Your children would be dead to. Your grandchildren, they might be around when it finished...

Code for Max Value Calculation

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;

public class MainLongMaxTest {

    // /*
    public static final long MAX_VALUE = Long.MAX_VALUE;
    public static long value = 0;
    public static long previousValue = 0;
    // */

    /*
    public static final int MAX_VALUE = Integer.MAX_VALUE;
    public static int value = 0;
    public static int previousValue = 0;
    */

    public static boolean done;
    public static BigDecimal startTime;
    public static BigDecimal endTime;

    public static void main(String[] args) {

        Runnable task = new StatusPrinterRunnable();
        new Thread(task).start(); // code waits 1 second before result printing loop

        done = false;
        startTime = new BigDecimal(System.currentTimeMillis());

        while(value >= 0) {
            previousValue = value;
            value += 1;
        }

        endTime = new BigDecimal(System.currentTimeMillis());
        done = true;
    }
}

class StatusPrinterRunnable implements Runnable {

    public static final NumberFormat numberFormat = NumberFormat.getNumberInstance();
    private static long SLEEP_TIME = 1000;

    @Override
    public void run() {

        try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e);   }
        while(!MainLongMaxTest.done) {  
            long value                  = MainLongMaxTest.value;
            //long valuesLeft           = MAX_VALUE - value;

            BigDecimal maxValueBd       = new BigDecimal(MainLongMaxTest.MAX_VALUE);
            BigDecimal valueBd          = new BigDecimal(value);
            BigDecimal differenceBd     = maxValueBd.subtract(valueBd);
            BigDecimal percentLeftBd    = differenceBd.divide(maxValueBd, 25, RoundingMode.HALF_DOWN);
            percentLeftBd               = percentLeftBd.multiply(new BigDecimal(100));
            String numberAsString       = numberFormat.format(value);
            String percentLeftAsString  = percentLeftBd.toString();
            String message = "" + numberAsString + "\t" + percentLeftAsString + " % left";
            System.out.println(message);

            try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e);   }
        }

        BigDecimal msTaken = MainLongMaxTest.endTime.subtract(MainLongMaxTest.startTime);
        BigDecimal secondsTaken = msTaken.divide(new BigDecimal("1000"));

        System.out.println();
        System.out.println("Max Value: " + numberFormat.format(MainLongMaxTest.previousValue));
        System.out.println("Time Taken (seconds): " + secondsTaken);
    }
}

I think your logic is correct just it will take a lot of time to reach that value.

the maximum Long value can hold is Long.MAX_value which is 9223372036854775807L

to speed up the logic, I modified the program as below and got the expected result.

public static void main(String args[]) {
        long i = 9223372036854775806L;
        long result = 0L;

        for (; ; ) {
            result = i++;
            if (i<0) {
              System.out.println("result"+result);
             System.out.println("i"+i);

             break;
            }
        }
        System.out.println("The biggest integer: is" + result);

}

Output:

result9223372036854775807 i-9223372036854775808 The biggest integer: is9223372036854775807

result has the maximum value it can hold after that it changes to its minimum value.

You can get the result in one step if you take advantage of binary algebra by:

result = -1L >>> 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