Martin Buchholz wrote:
> Peter,
> 
> Thanks.
> 
> I agree that previousClearBit, previousSetBit are worth
> adding to BitSet and intend to work on integrating your
> contribution soon.
> 
> BitSet has not seen a lot of maintenance the past few
> years, but I have been involved with most of it.
> 
> Martin
> 

Thanks Martin. There was a bug in the documentation. Here's an updated diff.

-- 
Peter B. West <http://cv.pbw.id.au/>
Folio <http://defoe.sourceforge.net/folio/>
--- openjdk/j2se/src/share/classes/java/util/BitSet.java	2007-07-05 17:49:27.000000000 +1000
+++ openjdk.mods/j2se/src/share/classes/java/util/BitSet.java	2007-07-18 23:41:11.000000000 +1000
@@ -593,6 +593,81 @@
     }
 
     /**
+     * Returns the index of the nearest bit that is set to <code>true</code>
+     * that occurs on or before the specified starting index. If no such
+     * bit exists then -1 is returned.
+     * 
+     * To iterate over the <code>true</code> bits in a <code>BitSet</code>,
+     * use the following loop:
+     * 
+     * <pre>
+     * int i = bs.previousSetBit(bs.length);
+     * while (i >= 0) {
+     *     // operate on index i here
+     *     if (--i >= 0) {
+     *          i = bs.previousSetBit(i);
+     *     }
+     * }
+     * 
+     * @param fromIndex the index to start checking from (inclusive).
+     * @return the index of the previous set bit.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int previousSetBit(int fromIndex) {
+	if (fromIndex < 0)
+	    throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
+
+	checkInvariants();
+
+        int u = wordIndex(fromIndex);
+        if (u >= wordsInUse) {
+            return length() - 1;
+        }
+            
+        long mask = (WORD_MASK << fromIndex + 1) ^ WORD_MASK;
+	long word = words[u] & ( mask != 0 ? mask : WORD_MASK );
+
+	while (true) {
+	    if (word != 0)
+		return (u * BITS_PER_WORD) + BIT_INDEX_MASK - Long.numberOfLeadingZeros(word);
+	    if (u-- == 0)
+		return -1;
+	    word = words[u];
+	}
+    }
+
+    /**
+     * Returns the index of the nearest bit that is set to <code>false</code>
+     * that occurs on or before the specified starting index.
+     *
+     * @param   fromIndex the index to start checking from (inclusive).
+     * @return  the index of the previous clear bit.
+     * @throws  IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int previousClearBit(int fromIndex) {
+	if (fromIndex < 0)
+	    throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
+
+	checkInvariants();
+
+        int u = wordIndex(fromIndex);
+        if (u >= wordsInUse) {
+            return fromIndex;
+        }
+
+        long mask = (WORD_MASK << fromIndex + 1) ^ WORD_MASK;
+	long word = ~words[u] & ( mask != 0 ? mask : WORD_MASK );
+
+	while (true) {
+	    if (word != 0)
+		return (u * BITS_PER_WORD) + BIT_INDEX_MASK - Long.numberOfLeadingZeros(word);
+	    if (u-- == 0)
+		return -1;
+	    word = ~words[u];
+	}
+    }
+
+    /**
      * Returns the "logical size" of this <code>BitSet</code>: the index of
      * the highest set bit in the <code>BitSet</code> plus one. Returns zero
      * if the <code>BitSet</code> contains no set bits.

Reply via email to