在java中打印出“long”数据类型中的每个数字

时间:2015-10-19 21:58:05

标签: java long-integer illegalargumentexception println

我尝试在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("");
}

1 个答案:

答案 0 :(得分:0)

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

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

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

好吧,一旦你花了appx。 150年(根据评论中提到的 Oliver Charlesworth 的计算)tot标题中的while成为9,223,372,036,854,700,000
tot循环后,100,000始终是for的倍数,因为其中‹0..9,999› < 10000+ 10

以下while周期将打印以下内容(添加换行符和格式以便于阅读):

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

这称为(arithmetic) overflow

对于另一个appx,此类tot将比9223372036854775807L,a.k.a。Long.MAX_VALUE更少,因此为负。 150年,直到它再次变为正,然后整个循环再次开始,一遍又一遍。

为什么会这样?

嗯,只有tot值可以让(tot < 9223372036854775807L)评估为false离开while循环:正是这个9_223_372_036_854_775_807L,又名Long.MAX_VALUE,因为没有比这更大的long值。

但是你在for循环中“隐藏”了这个数字(请参阅上面的输出并记住tot总是for循环之外的100,000的倍数)以便{{ 1}}永远不会有机会对其进行评估。

我将按如下方式实施:

(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 magic numbers一样糟糕。 9223372036854775807L(自Java 7以来)稍微好一些,但Java API为此提供了9_223_372_036_854_775_807L
  • 我同意,可以争论是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)+" "); 中创建(空)String的隐含实例毫无意义。