Как вы делаете ДЕЙСТВИТЕЛЬНО большие логические массивы с помощью Java?

Когда я пытаюсь создать очень большой логический массив с помощью Java, например:

    boolean[] isPrime1 = new boolean[600851475144];

Я получаю возможную ошибку потери точности?

Он слишком большой?


person Miamian    schedule 19.01.2009    source источник


Ответы (10)


Чтобы хранить 600 миллиардов битов, вам необходимо как минимум 75 гигабайт адресного пространства! Удачи с этим!

Хуже того, в спецификации Java не указано, что массив boolean будет использовать один бит памяти для каждого элемента — это могло бы (а в некоторых случаях) использует больше.

В любом случае, я узнаю этот номер из Project Euler #3. Если ему нужно так много памяти, вы делаете это неправильно...

person Alnitak    schedule 19.01.2009

Рассмотрите возможность использования BitSet.

person Hilton Campbell    schedule 19.01.2009
comment
Индекс BitSet для операций получения/установки является целым, а не длинным. - person Paul Tomblin; 19.01.2009
comment
Bitset действительно уменьшает необходимый размер только на 1/8. Значение, которое использует спрашивающий, более чем в 8 раз превышает максимальное значение длины массива. - person JaredPar; 19.01.2009
comment
Правда, BitSet не даст вам нужного размера. Тем не менее, это все еще отличная коллекция для использования в такой ситуации. - person Hilton Campbell; 19.01.2009

Поскольку вы пытаетесь решить задачу Эйлера №3 неправильным способом, вот подсказка: вы должны найти все простые множители числа, а не все простые числа< /strong> ниже определенного предела.

Кстати: эта конкретная проблема Эйлера может быть решена с использованием очень небольшого объема оперативной памяти.

person JesperE    schedule 19.01.2009
comment
да, я был совершенно ошибочным в моей первой попытке. Спасибо за совет. по крайней мере, я узнал немного из этих комментариев. - person Miamian; 19.01.2009

Индекс массива представляет собой целое число, а не длинное, поэтому ваш «массив» слишком велик, чтобы поместиться в массив. Один из классов java Collection может быть более подходящим. Неважно — Collection.size() также возвращает целое число, поэтому Collection также не может хранить более Integer.MAX_VALUE элементов.

person Paul Tomblin    schedule 19.01.2009
comment
@Alnitak - я понял это и редактировал, когда вы разместили свой комментарий. - person Paul Tomblin; 19.01.2009
comment
Технически Коллекция может хранить больше элементов, чем Integer.MAX_VALUE --- size() просто возвращает Integer.MAX_VALUE, когда это происходит. java.sun.com/javase/ 6/docs/api/java/util/Collection.html#size() - person Zach Scrivena; 19.01.2009

Гм... это будет около 70 ГБ логических значений. Не сработает. Ни за что.

person Michael Borgwardt    schedule 19.01.2009
comment
Это может... в терабайтной системе. - person Lawrence Dol; 20.01.2009

Проблема в том, что вы используете длинное значение вместо значения int для размера массива. Java не поддерживает длину массива больше, чем максимальное значение типа int. Java обрабатывает вашу длину как длинную, потому что указанный вами размер превышает максимальное значение для int, но укладывается в длину. Следовательно, он должен преобразовать длину обратно в int, чтобы создать массив. Преобразование из long -> int выдает предупреждение, которое вы видите

person JaredPar    schedule 19.01.2009

Вы можете использовать массив длинных значений, инкапсулированный в класс, который будет обрабатывать все операции над массивом. Что-то вроде вашей собственной реализации BitSet.

person Null303    schedule 19.01.2009
comment
Не уверен, почему за это проголосовали, поскольку это практически единственный способ приблизиться к этому количеству битов в одной структуре данных в Java (при условии, что у вас есть 64-битная виртуальная машина, чтобы иметь возможность адресовать такой большой объем памяти). Вам потребуется как минимум 3 массива длинных чисел, чтобы иметь возможность упаковать это количество битов. - person Dan Dyer; 19.01.2009

Почему бы просто не сохранить значения в файле, а затем найти позицию в файле и получить нужное значение. Как заявляли другие, это 70 ГБ данных. В большинстве случаев вы даже не сможете удержать это в памяти. Если вы собираетесь сохранить его в файл, вы можете даже просмотреть отдельные биты при сохранении и извлечении данных с помощью побитовых операторов, чтобы сэкономить место для хранения.

Кроме того, поскольку количество простых чисел уменьшается с размером чисел, возможно, лучше просто хранить сами простые числа в файле по порядку, а затем выполнять двоичный поиск числа, чтобы увидеть, является ли оно одним из простых чисел. .

person Kibbee    schedule 19.01.2009

Какие значения у вас есть в массиве? Для такого большого числа, я думаю, это будет разреженный массив, поэтому, возможно, было бы лучше использовать карту/список и просто выделить место и сохранить значение для значения 1 на бит. Или для значения 0, если большинство ваших значений будет равно 1.

person Cristian Vat    schedule 19.01.2009

Apache ActiveMQ имеет структуру данных под названием BitArrayBin. Это используется, чтобы узнать, дублируется ли сообщение. Идентификатор сообщения представляет собой комбинацию идентификатора производителя и идентификатора последовательности. У каждого производителя будет BitArrayBin для отслеживания его идентификаторов последовательности. Как только он находит BitArrayBin для данного производителя, он устанавливает идентификатор последовательности, который является длинным значением, равным BitArrayBin.

 oldValue = bitArrayBin.setBit(sequenceId, true)
 if (oldVlaue) {
   "message is duplicated"
 }

Метод возвращает старое значение.

Если y является длинным индексом, он используется для получения индекса интервала и смещения в нем.

y = bin index * 64 + offset

BitArrayBin — это не что иное, как держатель для множества бинов, размер которых можно определить при его построении. Каждый бин содержит длинную переменную для хранения битов, поэтому он может хранить до 64 логических значений.

Битовая маскировка используется для установки бита, а затем для получения его значения.

Этот класс не имеет много документации. Вам нужно просмотреть его исходный код, чтобы узнать внутренности.

введите здесь описание изображения

person Satish    schedule 05.02.2013