summaryrefslogtreecommitdiff
path: root/elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java')
-rw-r--r--elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java218
1 files changed, 218 insertions, 0 deletions
diff --git a/elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java b/elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java
new file mode 100644
index 00000000..879c4194
--- /dev/null
+++ b/elki/src/test/java/de/lmu/ifi/dbs/elki/utilities/BitsUtilTest.java
@@ -0,0 +1,218 @@
+package de.lmu.ifi.dbs.elki.utilities;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2015
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import static org.junit.Assert.*;
+
+import java.math.BigInteger;
+import java.util.BitSet;
+import java.util.Random;
+
+import org.junit.Test;
+
+import de.lmu.ifi.dbs.elki.JUnit4Test;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+
+/**
+ * Test bit manipulation code.
+ *
+ * @author Erich Schubert
+ * @since 0.5.0
+ */
+public class BitsUtilTest implements JUnit4Test {
+ @Test
+ public void testAgainstBigInteger() {
+ BigInteger bigint = new BigInteger("123");
+ long[] bituti = BitsUtil.make(Long.SIZE, 123);
+ assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
+
+ bigint = bigint.shiftLeft(13);
+ BitsUtil.shiftLeftI(bituti, 13);
+ assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
+
+ bigint = bigint.shiftRight(15);
+ BitsUtil.shiftRightI(bituti, 15);
+ assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
+ }
+
+ @Test
+ public void testSimpleOperations() {
+ long[] test = BitsUtil.zero(128);
+ BitsUtil.setI(test, 5);
+ BitsUtil.setI(test, 7);
+ assertEquals(BitsUtil.toString(test), "10100000");
+ assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
+ BitsUtil.truncateI(test, 7);
+ assertEquals(BitsUtil.toString(test), "100000");
+ assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
+ BitsUtil.setI(test, 7);
+ assertEquals(BitsUtil.toString(test), "10100000");
+ assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
+ BitsUtil.cycleRightI(test, 6, 8);
+ assertEquals(BitsUtil.toString(test), "10000010");
+ assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 1);
+ assertEquals(BitsUtil.numberOfTrailingZeros(test), 1);
+
+ BitsUtil.zeroI(test);
+ BitsUtil.setI(test, 125);
+ BitsUtil.setI(test, 60);
+ BitsUtil.cycleRightI(test, 70, 128);
+ assertTrue(BitsUtil.get(test, 55));
+ assertTrue(BitsUtil.get(test, 118));
+ assertEquals(BitsUtil.cardinality(test), 2);
+ BitsUtil.cycleLeftI(test, 70, 128);
+ assertTrue(BitsUtil.get(test, 125));
+ assertTrue(BitsUtil.get(test, 60));
+ assertEquals(BitsUtil.cardinality(test), 2);
+ }
+
+ @Test
+ public void testSorting() {
+ final Random r = new Random(0);
+ final int cnt = 100;
+ long[] rnds = new long[cnt];
+ long[][] bits = new long[cnt][];
+ for (int i = 0; i < cnt; i++) {
+ rnds[i] = Math.abs(r.nextLong());
+ bits[i] = BitsUtil.make(Long.SIZE, rnds[i]);
+ }
+
+ for (int i = 0; i < cnt; i++) {
+ for (int j = 0; j < cnt; j++) {
+ assertEquals(compare(rnds[i], rnds[j]), BitsUtil.compare(bits[i], bits[j]));
+ }
+ }
+
+ for (int i = 0; i < cnt; i++) {
+ long[] btmp = BitsUtil.copy(bits[i], 64 + r.nextInt(500));
+ assertEquals(BitsUtil.compare(btmp, bits[i]), 0);
+ for (int j = 0; j < cnt; j++) {
+ assertEquals(compare(rnds[i], rnds[j]), BitsUtil.compare(btmp, bits[j]));
+ }
+ }
+
+ for (int i = 0; i < cnt; i++) {
+ long[] btmp = BitsUtil.truncateI(BitsUtil.copy(bits[i]), 47);
+ for (int j = 0; j < cnt; j++) {
+ assertEquals(compare(rnds[i] & ((1 << 48) - 1), rnds[j]), BitsUtil.compare(btmp, bits[j]));
+ }
+ }
+
+ for (int i = 0; i < cnt; i++) {
+ long[] btmp = BitsUtil.cycleRightI(BitsUtil.copy(bits[i]), 13, Long.SIZE - 32);
+ long ltmp = BitsUtil.cycleRightC(rnds[i], 13, Long.SIZE - 32);
+ for (int j = 0; j < cnt; j++) {
+ assertEquals(compare(ltmp, rnds[j]), BitsUtil.compare(btmp, bits[j]));
+ }
+ }
+ }
+
+ /**
+ * Not jet in Java 6. To come in JDK7 as Long.copmare
+ *
+ * @param x
+ * @param y
+ * @return
+ */
+ public static int compare(long x, long y) {
+ return (x < y) ? -1 : ((x == y) ? 0 : 1);
+ }
+
+ @Test
+ public void testAgainstBitSet() {
+ BitSet bitset = new BitSet();
+ long[] bituti = BitsUtil.zero(Long.SIZE);
+ for (int i = 0; i >= 0;) {
+ assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
+ i = bitset.nextSetBit(i + 1);
+ }
+ // Java 7:
+ // assertEquals("Bit strings do not agree.",
+ // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
+
+ bitset.set(4);
+ BitsUtil.setI(bituti, 4);
+ for (int i = 0; i >= 0;) {
+ assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
+ i = bitset.nextSetBit(i + 1);
+ }
+ // Java 7:
+ // assertEquals("Bit strings do not agree.",
+ // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
+
+ bitset.set(15);
+ BitsUtil.setI(bituti, 15);
+ for (int i = 0; i >= 0;) {
+ assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
+ i = bitset.nextSetBit(i + 1);
+ }
+ // Java 7:
+ // assertEquals("Bit strings do not agree.",
+ // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
+
+ assertEquals(bitset.nextSetBit(0), BitsUtil.nextSetBit(bituti, 0));
+ assertEquals(bitset.nextSetBit(4), BitsUtil.nextSetBit(bituti, 4));
+ assertEquals(bitset.nextSetBit(5), BitsUtil.nextSetBit(bituti, 5));
+ // previousSetBit is not in JDK6.
+ // assertEquals(bitset.previousSetBit(64), BitsUtil.previousSetBit(bituti,
+ // 64));
+ // assertEquals(bitset.previousSetBit(15), BitsUtil.previousSetBit(bituti,
+ // 15));
+ // assertEquals(bitset.previousSetBit(14), BitsUtil.previousSetBit(bituti,
+ // 14));
+ }
+
+ @Test
+ public void testGrayCoding() {
+ long[] bits = BitsUtil.zero(123);
+ long[] ones = BitsUtil.ones(123);
+ BitsUtil.flipI(bits, 122);
+ BitsUtil.invgrayI(bits);
+ BitsUtil.xorI(bits, ones);
+ assertTrue(BitsUtil.isZero(bits));
+ BitsUtil.xorI(bits, ones);
+ BitsUtil.grayI(bits);
+ assertTrue(BitsUtil.get(bits, 122));
+ assertEquals(1, BitsUtil.cardinality(bits));
+ }
+
+ @Test
+ public void testLeadingTrailing() {
+ int[] testi = new int[] { 0x7, 0x12345678, 0x23456789, 0x45678900, 0x89000000, 0xFFFF0000 };
+ int[] truli = new int[] { 29, 3, 2, 1, 0, 0 };
+ int[] truti = new int[] { 0, 3, 0, 8, 24, 16 };
+ for (int i = 0; i < testi.length; i++) {
+ assertEquals("Leading zeros don't agree for " + BitsUtil.toString(testi[i]), truli[i], BitsUtil.numberOfLeadingZeros(testi[i]));
+ assertEquals("Trailing zeros don't agree for " + BitsUtil.toString(testi[i]), truti[i], BitsUtil.numberOfTrailingZeros(testi[i]));
+ }
+
+ long[] testl = new long[] { 0x7L, 0x12345678L, 0x23456789L, 0x45678900L, 0x89000000L, 0x1FFFF0000L, 0x123456789ABCDEFL, 0x0011001188008800L };
+ int[] trull = new int[] { 61, 35, 34, 33, 32, 31, 7, 11 };
+ int[] trutl = new int[] { 0, 3, 0, 8, 24, 16, 0, 11 };
+ for (int i = 0; i < testl.length; i++) {
+ assertEquals("Leading zeros don't agree for " + BitsUtil.toString(testl[i]), trull[i], BitsUtil.numberOfLeadingZeros(testl[i]));
+ assertEquals("Trailing zeros don't agree for " + BitsUtil.toString(testl[i]), trutl[i], BitsUtil.numberOfTrailingZeros(testl[i]));
+ }
+ }
+}