繁体   English   中英

在Java中以“长”数据类型打印出每个数字

[英]Printing out every number in a “long” datatype in java

我尝试打印出long数据类型中的每个数字,但在大约1,000,000,000个数字后收到此错误消息:

IllegalArgumentException:不合逻辑的文本范围从1072890159到-1072593439

我如何才能超越这一点?

long tot = 0;
while (tot < 9223372036854775807L)
{
    //This for loop makes sure that instead of printing out 200 000 numbers in 27 sec it
    //will take less than 3 seconds to print out about 500 000 numbers
    for (int i = 0; i < 10000; i++)
    {
        tot = tot + 10; 
        System.out.print(tot+" "+(tot+1)+" "+(tot+2)+" "+(tot+3)+" "+(tot+4)+" "+(tot+5)
                            +" "+(tot+6)+" "+(tot+7)+" "+(tot+8)+" "+(tot+9)+" "); 
    }

    System.out.println("");
}

您不会使用此代码段“以long数据类型打印出每个数字 ”。

首先,从10开始打印正数。 尝试用byte进行检查,但准备快速中止运行,因为...

其次, while循环永远不会结束。 为什么这个?

好吧,一旦您花了约apx。 150年(根据评价提到奥利弗查尔斯沃思的计算) totwhile头变得9,223,372,036,854,700,000
tot是总的倍数100,000for循环由于‹0..9,999› < 10000+ 10在其中。)

while循环中将打印以下内容(添加了换行符和格式以方便阅读):

 ...
 9223372036854775800  9223372036854775801  9223372036854775802
 9223372036854775803  9223372036854775804  9223372036854775805
 9223372036854775806  9223372036854775807 -9223372036854775808
-9223372036854775807 -9223372036854775806 -9223372036854775805
-9223372036854775804 -9223372036854775803 -9223372036854775802
 ...

这被称为(算术)溢出

由于是负数,因此此tot会小于另一个Long.MAX_VALUE 9223372036854775807L (也称为Long.MAX_VALUE 150年,直到它再次变为正,然后整个循环又一次又一次地开始。

为什么会这样?

好吧, 只有一个可以使(tot < 9223372036854775807L)tot(tot < 9223372036854775807L)评估为false以退出while循环:正是9_223_372_036_854_775_807L ,也就是Long.MAX_VALUE ,因为没有比这个更大的long值了。

但是,您是在“ for循环中“隐藏”此数字(请参见上面的输出,并记住,“ tot始终是for循环之外的100,000的倍数),因此(tot < 9223372036854775807L)永远没有机会对其进行评估。

我将实现如下:

public class Integers {

    public static void main(final String[] args) {

        printNumbersBetween(Byte.MIN_VALUE, Byte.MAX_VALUE);
        printNumbersBetween(Short.MIN_VALUE, Short.MAX_VALUE);
        printNumbersBetween(Character.MIN_VALUE, Character.MAX_VALUE);
        // printNumbersBetween(Integer.MIN_VALUE, Integer.MAX_VALUE);
        // printNumbersBetween(Long.MIN_VALUE, Long.MAX_VALUE);

    } // main(...)

    public static void printNumbersBetween(final long minValue, final long maxValue) {

        long n = minValue;
        while (n < maxValue) {
            // Count of numbers to be printed at once is preferably a power of two,
            // since the counts of numbers in the domains of all primitives divide nicely by it.
            // Such avoiding having to extra handle the last print cycle which is not "full".
            // E.g.: byte -> 256 numbers -> (discouraged) chunks of 10 -> 25 * 10 + 6[!].
            System.out.printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d%n",
                n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++, n++);
        }

    } // printNumbersBetween(...)

} // Integers

除了上述内容外,让我对您的编码风格发表一些评论:

  • 9223372036854775807L就像魔术数字一样糟糕。 9_223_372_036_854_775_807L (自Java 7起)会稍好一些,但Java API正是为此提供了Long.MAX_VALUE
  • 我同意,可以争论是tot += 10还是tot = tot + 10; 是首选。 我不坚持。
  • 这些行:

     System.out.printf("%d %d %d %d %d %d %d %d %d %d ", tot, tot+1, tot+2, tot+3, tot+4, tot+5, tot+6, tot+7, tot+8, tot+9);` 

    相比:

     System.out.print(tot+" "+(tot+1)+" "+(tot+2)+" "+(tot+3)+" "+(tot+4)+" "+(tot+5) +" "+(tot+6)+" "+(tot+7)+" "+(tot+8)+" "+(tot+9)+" "); 

    更容易阅读和理解,不是吗? 而且它也更短。

  • System.out.println("");创建(空) String的隐式实例System.out.println(""); 是没有意义的。

暂无
暂无

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

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