FileDocCategorySizeDatePackage
BitLevel.javaAPI DocAndroid 1.5 API12473Wed May 06 22:41:04 BST 2009java.math

BitLevel

public class BitLevel extends Object
Static library that provides all the bit level operations for {@link BigInteger}. The operations are:
  • Left Shifting
  • Right Shifting
  • Bit clearing
  • Bit setting
  • Bit counting
  • Bit testing
  • Getting of the lowest bit set
All operations are provided in immutable way, and some in both mutable and immutable.
author
Intel Middleware Product Division
author
Instituto Tecnologico de Cordoba

Fields Summary
Constructors Summary
private BitLevel()
Just to denote that this class can't be instantiated.

Methods Summary
static intbitCount(java.math.BigInteger val)

see
BigInteger#bitCount()

        // BEGIN android-added
        val.establishOldRepresentation("BitLevel.bitCount");
        // END android-added
        int bCount = 0;

        if (val.sign == 0) {
            return 0;
        }
        
        int i = val.getFirstNonzeroDigit();;
        if (val.sign > 0) {
            for ( ; i < val.numberLength; i++) {
                bCount += Integer.bitCount(val.digits[i]);
            }
        } else {// (sign < 0)
            // this digit absorbs the carry
            bCount += Integer.bitCount(-val.digits[i]);
            for (i++; i < val.numberLength; i++) {
                bCount += Integer.bitCount(~val.digits[i]);
            }
            // We take the complement sum:
            bCount = (val.numberLength << 5) - bCount;
        }
        return bCount;
    
static intbitLength(java.math.BigInteger val)

see
BigInteger#bitLength()

        // BEGIN android-added
        val.establishOldRepresentation("BitLevel.bitLength");
        // END android-added
        if (val.sign == 0) {
            return 0;
        }
        int bLength = (val.numberLength << 5);
        int highDigit = val.digits[val.numberLength - 1];

        if (val.sign < 0) {
            int i = val.getFirstNonzeroDigit();
            // We reduce the problem to the positive case.
            if (i == val.numberLength - 1) {
                highDigit--;
            }
        }
        // Subtracting all sign bits
        bLength -= Integer.numberOfLeadingZeros(highDigit);
        return bLength;
    
static java.math.BigIntegerflipBit(java.math.BigInteger val, int n)
Performs a flipBit on the BigInteger, returning a BigInteger with the the specified bit flipped.

param
intCount: the index of the element of the digits array where the operation will be performed
param
bitNumber: the bit's position in the intCount element

        // BEGIN android-added
        val.establishOldRepresentation("BitLevel.flipBit");
        // END android-added
        int resSign = (val.sign == 0) ? 1 : val.sign;
        int intCount = n >> 5;
        int bitN = n & 31;
        int resLength = Math.max(intCount + 1, val.numberLength) + 1;
        int resDigits[] = new int[resLength];
        int i;
        
        int bitNumber = 1 << bitN;
        System.arraycopy(val.digits, 0, resDigits, 0, val.numberLength);
        
        if (val.sign < 0) {
            if (intCount >= val.numberLength) {
                resDigits[intCount] = bitNumber;
            } else {
                //val.sign<0 y intCount < val.numberLength
                int firstNonZeroDigit = val.getFirstNonzeroDigit();
                if (intCount > firstNonZeroDigit) {
                    resDigits[intCount] ^= bitNumber;
                } else if (intCount < firstNonZeroDigit) {
                    resDigits[intCount] = -bitNumber;
                    for (i=intCount + 1; i < firstNonZeroDigit; i++) {
                        resDigits[i]=-1;
                    }
                    resDigits[i] = resDigits[i]--;
                } else {
                    i = intCount;
                    resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);
                    if (resDigits[i] == 0) {
                        for (i++; resDigits[i] == -1 ; i++) {
                            resDigits[i] = 0;
                        }
                        resDigits[i]++;
                    }
                }
            }
        } else {//case where val is positive
            resDigits[intCount] ^= bitNumber;
        }
        BigInteger result = new BigInteger(resSign, resLength, resDigits);
        result.cutOffLeadingZeroes();
        return result;
    
static voidinplaceShiftRight(java.math.BigInteger val, int count)
Performs {@code val >>= count} where {@code val} is a positive number.

        // BEGIN android-added
        val.establishOldRepresentation("BitLevel.inplaceShiftRight");
        // END android-added
        int sign = val.signum();
        if (count == 0 || val.signum() == 0)
            return;
        int intCount = count >> 5; // count of integers
        val.numberLength -= intCount;
        if (!shiftRight(val.digits, val.numberLength, val.digits, intCount,
                count & 31)
                && sign < 0) {
            // remainder not zero: add one to the result
            int i;
            for (i = 0; ( i < val.numberLength ) && ( val.digits[i] == -1 ); i++) {
                val.digits[i] = 0;
            }
            if (i == val.numberLength) {
                val.numberLength++;
            }
            val.digits[i]++;
        }
        val.cutOffLeadingZeroes();
        val.unCache();
    
static booleannonZeroDroppedBits(int numberOfBits, int[] digits)
Check if there are 1s in the lowest bits of this BigInteger

param
numberOfBits the number of the lowest bits to check
return
false if all bits are 0s, true otherwise

        int intCount = numberOfBits >> 5;
        int bitCount = numberOfBits & 31;
        int i;

        for (i = 0; (i < intCount) && (digits[i] == 0); i++) {
            ;
        }
        return ((i != intCount) || (digits[i] << (32 - bitCount) != 0));
    
static java.math.BigIntegershiftRight(java.math.BigInteger source, int count)

see
BigInteger#shiftRight(int)

        // BEGIN android-added
        source.establishOldRepresentation("BitLevel.shiftRight");
        // END android-added
        int intCount = count >> 5; // count of integers
        count &= 31; // count of remaining bits
        if (intCount >= source.numberLength) {
            return ((source.sign < 0) ? BigInteger.MINUS_ONE : BigInteger.ZERO);
        }
        int i;
        int resLength = source.numberLength - intCount;
        int resDigits[] = new int[resLength + 1];

        shiftRight(resDigits, resLength, source.digits, intCount, count);
        if (source.sign < 0) {
            // Checking if the dropped bits are zeros (the remainder equals to
            // 0)
            for (i = 0; (i < intCount) && (source.digits[i] == 0); i++) {
                ;
            }
            // If the remainder is not zero, add 1 to the result
            if ((i < intCount)
                    || ((count > 0) && ((source.digits[i] << (32 - count)) != 0))) {
                for (i = 0; (i < resLength) && (resDigits[i] == -1); i++) {
                    resDigits[i] = 0;
                }
                if (i == resLength) {
                    resLength++;
                }
                resDigits[i]++;
            }
        }
        BigInteger result = new BigInteger(source.sign, resLength, resDigits);
        result.cutOffLeadingZeroes();
        return result;
    
static booleanshiftRight(int[] result, int resultLen, int[] source, int intCount, int count)
Shifts right an array of integers. Total shift distance in bits is intCount * 32 + count.

param
result the destination array
param
resultLen the destination array's length
param
source the source array
param
intCount the number of elements to be shifted
param
count the number of bits to be shifted
return
dropped bit's are all zero (i.e. remaider is zero)

        int i;
        boolean allZero = true;
        for (i = 0; i < intCount; i++)
            allZero &= source[i] == 0;
        if (count == 0) {
            System.arraycopy(source, intCount, result, 0, resultLen);
            i = resultLen;
        } else {
            int leftShiftCount = 32 - count;

            allZero &= ( source[i] << leftShiftCount ) == 0;
            for (i = 0; i < resultLen - 1; i++) {
                result[i] = ( source[i + intCount] >>> count )
                | ( source[i + intCount + 1] << leftShiftCount );
            }
            result[i] = ( source[i + intCount] >>> count );
            i++;
        }
        
        return allZero;
    
static booleantestBit(java.math.BigInteger val, int n)
Performs a fast bit testing for positive numbers. The bit to to be tested must be in the range {@code [0, val.bitLength()-1]}

        // BEGIN android-added
        val.establishOldRepresentation("BitLevel.testBit");
        // END android-added
        // PRE: 0 <= n < val.bitLength()
        return ((val.digits[n >> 5] & (1 << (n & 31))) != 0);