Сообщение об ошибке «Слишком большое целое число» для 600851475143


89
public class Three {
    public static void main(String[] args) {
        Three obj = new Three();
        obj.function(600851475143);
    }

    private Long function(long  i) {
        Stack<Long> stack = new Stack<Long>();

        for (long j = 2; j <= i; j++) {
            if (i % j == 0) {
                stack.push(j);
            }
        }
        return stack.pop();
    }
}

Когда приведенный выше код запускается, он выдает ошибку в строке obj.function(600851475143);. Зачем?


1
также нет разницы между "л" и "л"?
user446654

@ user446654: Нет, есть. Последний более читабелен. Прочтите "Java Puzzler" для этого.
Адил Ансари,

@ user446654: развивающиеся мысли @Thilo о возможном превышении лимита памяти Я хочу добавить свои 2 монеты: вы выбрали действительно, очень плохой алгоритм для поиска всех делителей числа, если вы хотите работать с такими большими числами, как в вашем примере. Что-то, основанное на динамическом программировании , вероятно, подойдет лучше. Google по этому поводу для дальнейших результатов.
Роман

1
Добавлен тег PE, Project Euler # 3
st0le

@ st0le: IMHO вопрос определенно не об исходном решении проблемы, и то, что мы видим, тоже не является решением.
Роман

Ответы:


200

600851475143не может быть представлен как 32-битное целое число (тип int). Его можно представить как 64-битное целое число (тип long). длинные литералы в Java заканчиваются на "L":600851475143L


71

Append суффикс L: 23423429L.

По умолчанию java интерпретирует все числовые литералы как 32-битные целые числа. Если вы хотите явно указать, что это что-то большее, чем 32-битное целое число, вы должны использовать суффикс Lдля длинных значений.


Для тех, кто ищет более подробное объяснение того, почему вы получаете это сообщение об ошибке даже после того, как вы изменили тип переменной на long, прочтите это: stackoverflow.com/a/8924925/293280
Джошуа Пинтер

29

Вам нужно использовать длинный литерал:

obj.function(600851475143l);  // note the "l" at the end

Но я ожидал, что этой функции не хватит памяти (или времени) ...


17
считается лучшей практикой использовать lверхний регистр, чтобы его было легко отличить от1
Божо

2
@Bozho: Согласен. Но у меня есть опыт работы с Perl. Я кодирую "только для записи" :-)
Тило

Используйте «L» вместо «l»
Kevin V

13

Компилятор java пытается интерпретировать 600851475143 как постоянное значение типа int по умолчанию. Это вызывает ошибку, поскольку 600851475143 не может быть представлен с int.

Чтобы сообщить компилятору, что вы хотите, чтобы число интерпретировалось как длинное, вам нужно добавить либо одно, lлибо Lпосле него. Тогда ваш номер должен выглядеть так 600851475143L.

Поскольку некоторые шрифты затрудняют различение «1» и строчной буквы «l» друг от друга, вы всегда должны использовать верхний регистр «L».


6

Вам нужно 40 бит для представления целочисленного литерала 600851475143. Однако в Java максимальное целочисленное значение составляет 2 ^ 31-1 (т.е. целые числа 32-битные, см. Http://download.oracle.com/javase/1.4.2/docs /api/java/lang/Integer.html ).

Это не причем function. Попробуйте вместо этого использовать длинный целочисленный литерал (как предлагается в других ответах).


4

Во время компиляции число «600851475143» представляется в виде 32-битного целого числа, попробуйте вместо этого длинный литерал в конце вашего числа, чтобы решить эту проблему.


3

Помимо всех других ответов, вы можете сделать следующее:

long l = Long.parseLong("600851475143");

например :

obj.function(Long.parseLong("600851475143"));

1

Или вы можете объявить входной номер сколь угодно долго, а затем позволить ему исполнять кодовое танго: D ...

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);
    System.out.println("Enter a number");
    long n = in.nextLong();

    for (long i = 2; i <= n; i++) {
        while (n % i == 0) {
            System.out.print(", " + i);
            n /= i;
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.