📄 bigregister.java
字号:
* argument, returning -1, 0 or 1 for less than, equal to, or greater * than comparison result. * * @param x A <code>BigRegister</code> object to compare to. * @return -1, 0, +1 If the contents of <code>this</code> object are * respectively less than, equal to, or greater than those * of the argument. */ public synchronized int compareTo (BigRegister x) { if (size > x.size) return 1; if (size < x.size) return -1; return ArrayUtil.compared(bits, x.bits, true); }// Setters and getters//..................................................................... /** * Set the bit at the designated position to 1. * * @param n The bit position to alter. * @exception IllegalArgumentException If the argument would * cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array. */ public synchronized void setBit (int n) { if (n < 0 || n > size) throw new IllegalArgumentException(); bits[n / 8] |= 1 << (n % 8); } /** * Set <code>count</code> bits starting at offset <code>n</code> * to a given <code>value</code>. * * @param n The index of the first bit to set. * @param count Number of bits to set. * @param value New bits value, right justified in a <code>long</code>. * @exception IllegalArgumentException If any of the arguments would * cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array, or <code>count</code> is < 1 or * > 64. */ public synchronized void setBits (int n, int count, long value) { if (n < 0 || n > size || count < 1 || count > 64 || n + count > size) throw new IllegalArgumentException(); for (int i = 0, j = n; i < count; i++, j++) { if ((value & 0x01) == 1) bits[j / 8] |= 1 << (j % 8); // setBit(j); value >>>= 1; } } /** * Set the bit at the designated position to 0; ie. clear it. * * @param n The bit position to alter. * @exception IllegalArgumentException If the argument would * cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array. */ public synchronized void clearBit (int n) { if (n < 0 || n > size) throw new IllegalArgumentException(); bits[n / 8] &= ~(1 << (n % 8)); } /** * Flip the value of the bit at the designated position. * * @param n The bit position to alter. * @exception IllegalArgumentException If the argument would * cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array. */ public synchronized void flipBit (int n) { if (n < 0 || n > size) throw new IllegalArgumentException(); bits[n / 8] ^= 1 << (n % 8); } /** * Return 1 or 0 if the designated bit was set or cleared respectively. * * @param n The index of the bit to retrieve. * @exception IllegalArgumentException If the argument would * cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array. */ public synchronized int getBit (int n) { if (n < 0 || n > size) throw new IllegalArgumentException(); return ((bits[n / 8] & 0xFF) >> (n % 8)) & 0x01; } /** * Return <code>count</code> bits starting at offset <code>n</code> * framed in a <code>long</code>, right justified and left padded * with binary zeroes. * * @param n The index of the first bit to retrieve. * @param count Number of bits to retrieve. * @return Right justified <code>count</code> bits starting from bit * index <code>n</code> in a java <code>long</code>. * @exception IllegalArgumentException If any of the arguments * would cause an <code>ArrayOutOfBOundsException</code> while * accessing the bits array, or <code>count</code> is < 1 or * > 64. */ public synchronized long getBits (int n, int count) { if (n < 0 || n > size || count < 1 || count > 64 || n + count > size) throw new IllegalArgumentException(); long result = 0L; for (int i = 0, j = n + count - 1; i < count; i++, j--) result = result << 1 | (((bits[j / 8] & 0xFF) >> (j % 8)) & 0x01); return result; } /** * Return the rightmost byte value in <code>this BigRegister</code>. * * @return The rightmost byte value in <code>this</code>. */ public synchronized int byteValue () { return bits[0] & 0xFF; } /** * Return the rightmost 32-bit value in <code>this BigRegister</code> * as an <code>int</code>. * * @return The rightmost 32-bit value in <code>this</code> as an * <code>int</code>. */ public synchronized int intValue () { int offset = 0; int result = bits[offset++] & 0xFF; try { result |= (bits[offset++] & 0xFF) << 8 | (bits[offset++] & 0xFF) << 16 | (bits[offset ] & 0xFF) << 24; } catch (ArrayIndexOutOfBoundsException e) {} // when bits.length < 4 return result; } /** * Return the rightmost 64-bit value in <code>this BigRegister</code> * as a <code>long</code>. * * @return The rightmost 64-bit value in <code>this</code> as a <code> * long</code>. */ public synchronized long longValue () { int offset = 0; long result = bits[offset++] & 0xFFL; try { result |= (bits[offset++] & 0xFFL) << 8 | (bits[offset++] & 0xFFL) << 16 | (bits[offset++] & 0xFFL) << 24 | (bits[offset++] & 0xFFL) << 32 | (bits[offset++] & 0xFFL) << 40 | (bits[offset++] & 0xFFL) << 48 | (bits[offset ] & 0xFFL) << 56; } catch (ArrayIndexOutOfBoundsException e) {} // when bits.length < 8 return result; } /** * Return a <code>BigRegister</code>, of the same <code>size</code> * as <code>this</code> set to the specified value. * * @return A <code>BigRegister</code>, of the same <code>size</code> * as <code>this</code> set to the specified value. */ public synchronized BigRegister valueOf (long n) { BigRegister result = new BigRegister(size); int limit = Math.min(8, bits.length); for (int i = 0; i < limit; i++) result.bits[i] = (byte) (n >>> (8 * i)); result.pad(); return result; } /** Reset to zeroes all <code>this BigRegister</code>'s bits. */ public synchronized void reset () { ArrayUtil.clear(bits); } /** * Fill <code>this BigRegister</code> object with random data * generated from the default source. */ public synchronized void atRandom () { atRandom(prng); } /** * Fill <code>this BigRegister</code> object with random data * generated from a designated source. */ public synchronized void atRandom (SecureRandom source) { source.nextBytes(bits); pad(); } /** * Copy the argument's value into <code>this</code>. * * @exception IllegalArgumentException If the argument is of * different <code>size</code> than <code>this</code>. */ public synchronized void load (BigRegister source) { if (size != source.size) throw new IllegalArgumentException(); System.arraycopy(source.bits, 0, bits, 0, bits.length); } /** * Copy the bit values from a byte array into <code>this</code>. * Byte array order is assumed to have its Least Significant Byte * (LSB) at index position 0. This format mirrors that of the output * returned by the <code>toByteArray()</code> method. * <p> * Bits unprovided for in the <code>source</code> array are cleared. * It is a more tolerant way of initialising a register than that * obtained by invoking the same method with a <code>BigRegister</code> * argument. * * @param source The source bits organised in a byte array with * their LSB at index 0. * @exception IllegalArgumentException If the argument is of * greater <code>size</code> than <code>this</code>. * @see #toByteArray */ public synchronized void load (byte[] source) { int length = source.length; int limit = bits.length; if (length > limit) throw new IllegalArgumentException(); System.arraycopy(source, 0, bits, 0, length); if (length < limit) // clear the rest ArrayUtil.clear(bits, length, limit - length); pad(); } /** * Return a copy of <code>this BigRegister</code>'s contents in a * byte array with the LSB at index position 0. This format is * compatible with the <code>load([B)</code> method of this class. * * @return The bits of <code>this</code> in a byte array with the * LSB at index position 0. */ public synchronized byte[] toByteArray () { return (byte[]) (bits.clone()); } // Visualisation and introspection methods//..................................................................... /** * Return the <code>size</code> of <code>this</code> object as * specified at its instantiation time. * * @return The <code>size</code> of <code>this</code> object * as specified at its instantiation time. */ public synchronized int getSize () { return size; } /** * Return the number of bits set (to 1) in <code>this</code>. * * @return The number of set bits in <code>this</code>. */ public synchronized int countSetBits () { int count = 0; int limit = bits.length; for (int i = 0, j; i < limit; i++) { j = bits[i]; count += j < 0 ? 8 : log2x[j & 0xFF]; } return count; } /** * Return the index of the leftmost non-zero bit in <code>this</code>. * * @return Index of the leftmost non-zero bit in <code>this</code>, or * -1 if all bits are zeroes. */ public synchronized int highestSetBit () { int i = bits.length - 1; while (i > 0 && bits[i] == 0) i--; if (bits[i] == 0) return -1; int b = (bits[i] >>> 4) & 0x0F; int j = 4; if (b == 0) { b = bits[i] & 0x0F; j -= 4; } j += high[b]; return i * 8 + j; } /** * Return the index of the rightmost non-zero bit in <code>this</code>. * * @return Index of the rightmost non-zero bit in <code>this</code>, or * -1 if all bits are zeroes. */ public synchronized int lowestSetBit () { int i = 0; int limit = bits.length; while (i < limit && bits[i] == 0) i++; if (i == limit) return -1; int b = bits[i] & 0x0F; int j = 0; if (b == 0) { b = (bits[i] >>> 4) & 0x0F; j += 4; } j += low[b]; return i * 8 + j; } /** * Return a formatted <code>String</code> representation of the binary * contents of <code>this</code>. * * @return A formatted string representation of the binary contents * of <code>this</code>. */ public synchronized String toString () { StringBuffer sb = new StringBuffer(8 * bits.length + 64); sb.append("Binary dump of a BigRegister [").append(size).append("-bit]...\n"); sb.append("Byte #:|........|........|........|........|........|........|........|........|\n"); int k = bits.length; // number of bytes int i, b; int first = k-- % 8; // number of bytes on 1st line String s; if (first != 0) { s = " " + String.valueOf(bits.length); sb.append(s.substring(s.length() - 6)).append(':'); for (i = 0; i < 8 - first; i++) sb.append(" "); for (i = 0; i < first; i++) { b = bits[k--] & 0xFF; sb.append(' '). append(binaryDigits[(b >>> 4) & 0x0F]). append(binaryDigits[b & 0x0F]); } sb.append('\n'); } int lines = (k + 1) / 8; // number of remaining 8-byte lines int j; for (i = 0; i < lines; i++) { s = " " + String.valueOf(8 * (lines - i)); sb.append(s.substring(s.length() - 6)).append(':'); for (j = 0; j < 8; j++) { b = bits[k--] & 0xFF; sb.append(' '). append(binaryDigits[(b >>> 4) & 0x0F]). append(binaryDigits[b & 0x0F]); } sb.append('\n'); } sb.append('\n'); return sb.toString(); } // house-keeping//..................................................................... // ensure that bits to the left of 'size-1' are all zeroes private synchronized void pad () { int n = 8 - (size % 8); if (n != 8) bits[bits.length - 1] &= 0xFF >>> n; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -