简体   繁体   English

为什么我不能打印最大 long 值?

[英]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.我正在使用 for 循环编译 Java 程序以找出 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. long最大值约为 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.这意味着您需要经过 9 个 quintillion 循环,然后它才能缠绕并断裂。 I just tried to run 2 billion operations in my javascript console and times out for a couple of minutes before I force quit.我只是尝试在我的 javascript 控制台中运行 20 亿次操作,并在我强制退出之前超时几分钟。

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.或者,从接近最大值的地方开始i ,比如9,223,372,036,854,700,000 ,看看它是否仍然给你同样的问题。 In Java 8, adding underscore to numeric literals is allowed.在 Java 8 中,允许向数字文字添加下划线 Initializing i to something like 9_223_372_036_854_700_000L will give you something in a more timely manner.i初始化为9_223_372_036_854_700_000L类的9_223_372_036_854_700_000L会更及时地为您提供一些东西。

The max long is significantly high, at 9.223372e+18 .最大多头非常高,为9.223372e+18 For specifics , 9,223,372,036,854,775,807 is the number in question. 具体来说9,223,372,036,854,775,807是有问题的数字。 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.用单独的线程编写它,每1秒将结果更新到控制台。

"int" results “int”结果

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) 1,362,032,97 - 第二个和第三个值之间的差异(1 秒)
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 秒 - 达到 long 的最大值需要多少秒(Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 seconds = 214.73 years (per conversion by google search) 6,771,768,529 秒 = 214.73 年(谷歌搜索的每次转化)

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.所以如果我的计算是正确的......当普通计算机通过递增和检查它是否溢出来计算 long 的最大值时,你已经老了。 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最大 Long 值可以保存为 Long.MAX_value,即 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结果9223372036854775807 i-9223372036854775808 最大整数: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;结果 = -1L >>> 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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