为什么 Java `BitSet` 没有 `shiftLeft` 和 `shiftRight` 函数?

发布于 2025-01-01 15:50:06 字数 525 浏览 1 评论 0原文

这些缺失有什么特殊原因吗?

它们确实存在于 BigInteger 中,但由于 BigInteger 的不可变设计模式,它们通常非常慢。 BitSet 更好,因为它是可变的,但我真的很怀念 shift 函数(<<>> > 表示long)。对于 BitSet,就地移位以及循环旋转也很有用。

我已经看到了对 Shifting a Java BitSet 的回复(使用 get(off, len ) 用于移位;但这需要复制)。

别误会我的意思。我知道在哪里报告错误。我只是想知道是否有特定的原因省略它们,例如某种设计模式或这样的概念。特别是因为它们包含在BigInteger中。

Is there any particular reason why these are missing?

They do exist in BigInteger, but due to the immutable design pattern of BigInteger these are usually awfully slow. BitSet is much nicer because it is mutable, but I really miss the shift functions (<< and >>> for longs). For BitSet, an inplace shifting would also be useful, as well as cyclic rotation.

I have seen the reply to Shifting a Java BitSet (using get(off, len) for shifting; however this requires copying).

Don't get me wrong. I know where to report bugs. I'm just wondering if there was a particular reason to omit them, e.g. some design pattern or such a concept. In particular as they are included in BigInteger.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七色彩虹 2025-01-08 15:50:06

从概念上讲,BitSet 通常/经常用于跟踪大量设置,以便集合中的每个位都有特定的含义。因此,移位操作在这种情况下没有什么意义。

您显然已经发现了 BitSet 的另一个有用用途,但它超出了 BitSet 可能设想的范围。

Conceptually, a BitSet is typically / often used for tracking a lot of settings, such that each bit in the set has a specific meaning. So a shift operation makes little sense in that context.

You've clearly found another useful purpose for a BitSet, but it's outside the scope for which BitSet was probably envisioned.

自此以后,行同陌路 2025-01-08 15:50:06

我的猜测是,这会让他们的一些代码变得更加复杂。例如,如果你将所有内容“左移 3”,则可以有一个附加字段,shift,它是 -3(或者可能是 3,我只有 50% 的机会做对:-)。而且,对于 get() 和 set() 方法,如果您只是通过移位调整 bitIndex,代码应该可以工作。例如

public boolean get(int bitIndex) {
    bitIndex += shift;  // new code!!!
    if (bitIndex < 0)
        throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

    checkInvariants();

    int wordIndex = wordIndex(bitIndex);
    return (wordIndex < wordsInUse)
        && ((words[wordIndex] & (1L << bitIndex)) != 0);
    }

,但是,对于其他一些操作,例如 intersects() 和 or(),代码会开始变得非常混乱。现在 or() 方法的核心非常简单且快速:

 // Perform logical OR on words in common
   for (int i = 0; i < wordsInCommon; i++)
      words[i] |= set.words[i];

   // Copy any remaining words
   if (wordsInCommon < set.wordsInUse)
     System.arraycopy(set.words, wordsInCommon,
                  words, wordsInCommon,
              wordsInUse - wordsInCommon);

如果两个 BitSet 都有可能发生移位,这会很快变得混乱。他们可能认为如果你真的想转移,你应该使用 get 和 copy。

让我惊讶的一件事 - 在 get() 中,他们不执行 1L <<位索引&31。显然<<现在我想起了遥远的机器语言,这是有道理的。

My guess is that it would make some of their code way more complicated. For example, if you "left shift by 3" everything, you could have one additional field, shift, which is -3 (or maybe 3, I've only got a 50% chance to get it right :-) . And, for the get() and set() methods, if you simply adjust bitIndex by shift, the code should work. e.g.

public boolean get(int bitIndex) {
    bitIndex += shift;  // new code!!!
    if (bitIndex < 0)
        throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

    checkInvariants();

    int wordIndex = wordIndex(bitIndex);
    return (wordIndex < wordsInUse)
        && ((words[wordIndex] & (1L << bitIndex)) != 0);
    }

However, for some of the other operations, like intersects() and or(), the code would start getting really messy. Right now the core of the or() method is very simple and fast:

 // Perform logical OR on words in common
   for (int i = 0; i < wordsInCommon; i++)
      words[i] |= set.words[i];

   // Copy any remaining words
   if (wordsInCommon < set.wordsInUse)
     System.arraycopy(set.words, wordsInCommon,
                  words, wordsInCommon,
              wordsInUse - wordsInCommon);

If both BitSets had possible shifts this would get messy fast. They probably figured that if you really want to shift, you should use get and copy.

One thing that surprised me - in get(), they do not do 1L << bitIndex&31. Apparently << loops around, which, now that I remember my long distant machine language, makes sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文