9

当我尝试使用 Java 制作一个非常大的布尔数组时,例如:

    boolean[] isPrime1 = new boolean[600851475144];

我可能会丢失精度错误?

是不是太大了?

4

10 回答 10

16

要存储 6000亿位,您需要 75 GB的绝对最小地址空间!祝你好运!

更糟糕的是,Java 规范没有指定boolean数组将为每个元素使用一位内存——它可以(并且在某些情况下确实)使用更多。

无论如何,我从Project Euler #3中认出了这个数字。如果它需要那么多内存,那你就错了……

于 2009-01-19T17:57:43.500 回答
4

考虑使用BitSet

于 2009-01-19T17:53:18.237 回答
4

由于您试图以错误的方式解决欧拉问题#3,因此这里有一个提示:您应该找到一个数字的所有数,而不是低于某个限制的所有素数。

顺便说一句:这个特殊的欧拉问题可以使用非常少量的 RAM 来解决。

于 2009-01-19T18:22:24.120 回答
3

数组索引是 int,而不是 long,因此您的“数组”太大而无法放入数组中。 java Collection 类之一可能更适合。没关系 - Collection.size() 也返回一个 int,所以 Collection 也不能存储超过Integer.MAX_VALUE项目。

于 2009-01-19T17:52:41.060 回答
2

嗯......那将是大约 70GB 的布尔值。不会工作。没门。

于 2009-01-19T17:56:46.433 回答
2

您可以使用封装在一个类中的 long 数组,该类将处理数组上的所有操作。类似于您自己的 BitSet 实现。

于 2009-01-19T17:57:34.327 回答
2

问题是您使用的是 long 值与数组大小的 int 值。Java 不支持比 int 的最大值更长的数组长度。Java 将您的长度视为 long,因为您指定的大小超过了 int 的最大值但适合 long。因此,它必须将长度转换回 int 以创建数组。从 long -> int 的转换正在产生您看到的警告

于 2009-01-19T17:58:58.303 回答
1

为什么不将值存储在文件中,然后寻找文件中的位置并提取正确的值。就像其他人所说的那样,这是 70GB 的数据。在大多数情况下,您甚至无法将其保存在内存中。如果要将其存储到文件中,您甚至可以在使用位运算符存储和检索数据时查看各个位以节省存储空间。

此外,由于素数的数量随着数字的大小而减少,最好将素数本身按顺序存储在文件中,然后对该数字进行二进制搜索以查看它是否是素数之一.

于 2009-01-19T18:00:05.303 回答
1

你在数组中有什么值?对于这么大的数字,我猜这将是一个稀疏数组,所以最好使用 Map/List 并分配空间并存储一个 1 值的值。或者如果您的大多数值都是 1,则为 0 值。

于 2009-01-19T18:07:15.150 回答
1

Apache ActiveMQ 有一个名为 BitArrayBin 的数据结构。这用于查明消息是否重复。消息 ID 是生产者 ID 和序列 ID 的组合。每个生产者都有一个 BitArrayBin 来跟踪其序列 ID。一旦找到给定生产者的 BitArrayBin,它就会将序列 ID 设置为 BitArrayBin 的长值。

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

该方法返回旧值。

如果 y 是长索引,则它用于导出 bin 索引和其中的偏移量。

y = bin index * 64 + offset

BitArrayBin 只不过是许多 bin 的持有者,可以在其构建过程中定义大小。每个 bin 包含一个 long 变量来存储位,因此它可以存储多达 64 个布尔值。

位掩码用于设置位,然后获取它的值。

这个类没有太多的文档。你需要通过它的源代码来了解它的内部结构。

在此处输入图像描述

于 2013-02-05T12:45:13.163 回答