2015-10-19 6 views
0

Я попытался распечатывания каждый индивидуальный номер в long типа данных, но я получаю сообщение об ошибке после того, как о 1000000000 номеров:Распечатка каждого номера в «длинных» типов данных в Java

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(""); 
} 
+10

Это 2^63 значения; даже если вы напечатали одно значение за наносекунду (вероятно, как минимум на 3 порядка быстрее, чем реальность), понадобилось бы 300 лет, чтобы напечатать все это. –

+0

Я собираюсь предположить, что вы используете Netbeans? – azurefrog

+2

Это ошибка на NetBeans действительно https://netbeans.org/bugzilla/show_bug.cgi?id=181582 –

ответ

0

Вы НЕ «распечатки каждый индивидуальный номер в long типа данных» с этим фрагментом кода.

Во-первых, вы начинаете печатать положительные числа от 10 до. Попробуйте с byte проверить, но будьте готовы к быстрому прекращению работы, так как ...

Во-вторых, цикл while никогда не заканчивается. Почему это?

Ну, как только вы потратили приложение. 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.

таких tot будет меньше, так как отрицательный, чем 9223372036854775807L, a.k.a. Long.MAX_VALUE, для другого приложения. 150 лет, пока он снова не станет положительным, а затем весь цикл снова и снова начинается снова и снова.

Почему это происходит?

Ну, есть один и только один значение tot, что может сделать (tot < 9223372036854775807L) вычисляться false покинуть while цикл: именно этот 9_223_372_036_854_775_807L, a.k.a Long.MAX_VALUE, так как нет больше long значение, чем это.

Но «скрываются» этот номер внутри цикла for (см выход выше и помните, что tot всегда кратна 100000 за пределами цикла for), так что (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 так плохо, как может быть magic numbers , 9_223_372_036_854_775_807L (так как Java 7) будет немного лучше, но Long.MAX_VALUE предоставляется Java API именно для этого.
  • Согласен, можно утверждать, является ли 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 в System.out.println(""); бессмысленно.