簡體   English   中英

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

[英]Why can't I print the maximum long value?

我正在使用 for 循環編譯 Java 程序以找出 long 的最大值。 但是,當我運行程序時沒有打印任何內容。 為什么?

這是我的代碼:

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);
  }

主要是因為時間。

long最大值約為 9.22 quintillion。 您從零開始並逐漸增加。 這意味着您需要經過 9 個 quintillion 循環,然后它才能纏繞並斷裂。 我只是嘗試在我的 javascript 控制台中運行 20 億次操作,並在我強制退出之前超時幾分鍾。

如果你坐在那里讓它運行足夠長的時間,你就會得到你的輸出。 或者,從接近最大值的地方開始i ,比如9,223,372,036,854,700,000 ,看看它是否仍然給你同樣的問題。 在 Java 8 中,允許向數字文字添加下划線 i初始化為9_223_372_036_854_700_000L類的9_223_372_036_854_700_000L會更及時地為您提供一些東西。

最大多頭非常高,為9.223372e+18 具體來說9,223,372,036,854,775,807是有問題的數字。 這也有助於整個“這行得通,只是需要太長時間”的理論。

我很好奇需要多長時間,所以我寫了一個類來做同樣的事情。 用單獨的線程編寫它,每1秒將結果更新到控制台。

“int”結果

1,343,211,433   37.4518434691484288634492200 % left

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

“長”結果

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 - 第二個和第三個值之間的差異(1 秒)
6,771,768,529 秒 - 達到 long 的最大值需要多少秒(Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 秒 = 214.73 年(谷歌搜索的每次轉化)

所以如果我的計算是正確的......當普通計算機通過遞增和檢查它是否溢出來計算 long 的最大值時,你已經老了。 你的孩子會死的。 你的孫子們,完成后他們可能會在附近......

最大值計算代碼

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);
    }
}

我認為您的邏輯是正確的,只是需要很長時間才能達到該值。

最大 Long 值可以保存為 Long.MAX_value,即 9223372036854775807L

為了加快邏輯,我修改了如下程序並得到了預期的結果。

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);

}

輸出:

結果9223372036854775807 i-9223372036854775808 最大整數:is9223372036854775807

結果具有它可以保持的最大值,之后它會更改為最小值。

如果您通過以下方式利用二元代數,您可以一步得到結果:

結果 = -1L >>> 1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM