All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.util.BitHelper Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

package com.tangosol.util;


/**
* A collection of methods for bit-based operations.
*
* @author cp  2006.01.10  starting from the MemberSet implementation
*/
public class BitHelper
        extends Base
    {
    // ----- bit rotation ---------------------------------------------------

    /**
    * Rotate the bits of the passed byte value to the left by the number of
    * bits specified.
    *
    * @param b      a byte value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static byte rotateLeft(byte b, int cBits)
        {
        int n = b & 0xFF;
        cBits &= 0x7;
        return (byte) ((n >>> (8 - cBits)) | (n << cBits));
        }

    /**
    * Rotate the bits of the passed byte value to the right by the number of
    * bits specified.
    *
    * @param b      a byte value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static byte rotateRight(byte b, int cBits)
        {
        int n = b & 0xFF;
        cBits &= 0x7;
        return (byte) ((n >>> cBits) | (n << (8 - cBits)));
        }

    /**
    * Rotate the bits of the passed int value to the left by the number of
    * bits specified.
    *
    * @param n      an int value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static int rotateLeft(int n, int cBits)
        {
        return Integer.rotateLeft(n, cBits);
        }

    /**
    * Rotate the bits of the passed int value to the right by the number of
    * bits specified.
    *
    * @param n      an int value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static int rotateRight(int n, int cBits)
        {
        return Integer.rotateRight(n, cBits);
        }

    /**
    * Rotate the bits of the passed long value to the left by the number of
    * bits specified.
    *
    * @param n      a long value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static long rotateLeft(long n, int cBits)
        {
        return Long.rotateLeft(n, cBits);
        }

    /**
    * Rotate the bits of the passed long value to the right by the number of
    * bits specified.
    *
    * @param n      a long value
    * @param cBits  the number of bit rotations to perform
    *
    * @return the value with its bits rotated as indicated
    *
    * @since Coherence 3.5
    */
    public static long rotateRight(long n, int cBits)
        {
        return Long.rotateRight(n, cBits);
        }


    // ----- bit counting ---------------------------------------------------

    /**
    * Count the number of bits set in the passed integral value.
    *
    * @param b  a byte
    *
    * @return the number of bits set in the byte [0..8]
    */
    public static int countBits(byte b)
        {
        return BIT_COUNT[b & 0xFF];
        }

    /**
    * Count the number of bits set in the passed integral value.
    *
    * @param n  an int
    *
    * @return the number of bits set in the int [0..32]
    */
    public static int countBits(int n)
        {
        return Integer.bitCount(n);
        }

    /**
    * Count the number of bits set in the passed integral value.
    *
    * @param l  a long
    *
    * @return the number of bits set in the long [0..64]
    */
    public static int countBits(long l)
        {
        return Long.bitCount(l);
        }


    // ----- most significant bit (MSB) -------------------------------------

    /**
    * Determine the most significant bit of the passed integral value.
    *
    * @param b  a byte
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the most significant bit such that 1 << p is
    *         the most significant bit of b
    */
    public static int indexOfMSB(byte b)
        {
        return BIT_LEFTMOST[b & 0xFF];
        }

    /**
    * Determine the most significant bit of the passed integral value.
    *
    * @param n  an int
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the most significant bit such that 1 << p is
    *         the most significant bit of n
    */
    public static int indexOfMSB(int n)
        {
        return n == 0L ? -1 : Integer.numberOfTrailingZeros(Integer.highestOneBit(n));
        }

    /**
    * Determine the most significant bit of the passed integral value.
    *
    * @param l  a long
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the most significant bit such that 1 << p is
    *         the most significant bit of l
    */
    public static int indexOfMSB(long l)
        {
        return l == 0L ? -1 : Long.numberOfTrailingZeros(Long.highestOneBit(l));
        }


    // ----- least significant bit (LSB) ------------------------------------

    /**
    * Determine the least significant bit of the passed integral value.
    *
    * @param b  a byte
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the least significant bit such that 1 << p is
    *         the least significant bit of b
    */
    public static int indexOfLSB(byte b)
        {
        return BIT_RIGHTMOST[b & 0xFF];
        }

    /**
    * Determine the least significant bit of the passed integral value.
    *
    * @param n  an int
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the least significant bit such that 1 << p is
    *         the least significant bit of n
    */
    public static int indexOfLSB(int n)
        {
        return n == 0L ? -1 : Integer.numberOfTrailingZeros(Integer.lowestOneBit(n));
        }

    /**
    * Determine the least significant bit of the passed integral value.
    *
    * @param l  a long
    *
    * @return -1 if no bits are set; otherwise, the bit position p
    *         of the least significant bit such that 1 << p is
    *         the least significant bit of l
    */
    public static int indexOfLSB(long l)
        {
        return l == 0L ? -1 : Long.numberOfTrailingZeros(Long.lowestOneBit(l));
        }


    // ----- string formatting ----------------------------------------------

    /**
    * Convert a byte to a String of ones and zeros.
    *
    * @param b  a byte
    *
    * @return a String of ones and zeros representing the byte value
    */
    public static String toBitString(byte b)
        {
        char[] ach = new char[8];
        for (int i = 7; i >= 0; --i)
            {
            ach[i] = (char) ('0' + (b & 0x01));
            b >>>= 1;
            }
        return new String(ach);
        }

    /**
    * Convert an int to a String of ones and zeros.
    *
    * @param n  an int
    *
    * @return a String of ones and zeros representing the int value
    */
    public static String toBitString(int n)
        {
        char[] ach = new char[32];
        for (int i = 31; i >= 0; --i)
            {
            ach[i] = (char) ('0' + (n & 0x01));
            n >>>= 1;
            }
        return new String(ach);
        }

    /**
    * Convert a long to a String of ones and zeros.
    *
    * @param l  a long
    *
    * @return a String of ones and zeros representing the long value
    */
    public static String toBitString(long l)
        {
        char[] ach = new char[64];
        for (int i = 63; i >= 0; --i)
            {
            ach[i] = (char) ('0' + ((int) l & 0x01));
            l >>>= 1;
            }
        return new String(ach);
        }


    // ----- byte[] helpers -------------------------------------------------

    /**
     * Convert the specified int into a series of eight bytes, and write them
     * to the specified byte-array in big-endian form (MSB first).
     *
     * @param n   the int to convert to bytes
     * @param ab  the byte array to write into
     * @param of  the starting offset
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is shorter than of + 4
     */
    public static void toBytes(int n, byte[] ab, int of)
        {
        ab[of    ] = (byte) (n >>> 24);
        ab[of + 1] = (byte) (n >>> 16);
        ab[of + 2] = (byte) (n >>>  8);
        ab[of + 3] = (byte) (n);
        }

    /**
     * Convert the specified int into a byte array containing a series of eight
     * bytes in big-endian form (MSB first).
     *
     * @param l  the int to convert to bytes
     *
     * @return a byte[] representing the big-endian representation of the int
     */
    public static byte[] toBytes(int l)
        {
        byte[] ab = new byte[4];
        toBytes(l, ab, 0);
        return ab;
        }

    /**
     * Convert the specified long into a series of eight bytes, and write them
     * to the specified byte-array in big-endian form (MSB first).
     *
     * @param l   the long to convert to bytes
     * @param ab  the byte array to write into
     * @param of  the starting offset
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is shorter than of + 8
     */
    public static void toBytes(long l, byte[] ab, int of)
        {
        ab[of    ] = (byte) (l >>> 56);
        ab[of + 1] = (byte) (l >>> 48);
        ab[of + 2] = (byte) (l >>> 40);
        ab[of + 3] = (byte) (l >>> 32);
        ab[of + 4] = (byte) (l >>> 24);
        ab[of + 5] = (byte) (l >>> 16);
        ab[of + 6] = (byte) (l >>>  8);
        ab[of + 7] = (byte) (l);
        }

    /**
     * Convert the specified long into a byte array containing a series of eight
     * bytes in big-endian form (MSB first).
     *
     * @param l  the long to convert to bytes
     *
     * @return a byte[] representing the big-endian representation of the long
     */
    public static byte[] toBytes(long l)
        {
        byte[] ab = new byte[8];
        toBytes(l, ab, 0);
        return ab;
        }

    /**
     * Return the int represented by the sequence of eight bytes (in big-endian
     * form) in the specified byte-array starting at the given offset.
     *
     * @param ab  the byte-array
     * @param of  the offset
     *
     * @return the int represented by the sequence of bytes
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is less than of + 4
     */
    public static int toInt(byte[] ab, int of)
        {
        return    ((ab[of    ]       ) << 24)
                | ((ab[of + 1] & 0xFF) << 16)
                | ((ab[of + 2] & 0xFF) << 8 )
                | ((ab[of + 3] & 0xFF)      );
        }

    /**
     * Return the int represented by the sequence of eight bytes (in big-endian
     * form) in the specified byte-array.
     *
     * @param ab  the byte-array
     *
     * @return the int represented by the byte-array
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is less than 4
     */
    public static int toInt(byte[] ab)
        {
        return toInt(ab, 0);
        }

    /**
     * Return the long represented by the sequence of eight bytes (in big-endian
     * form) in the specified byte-array starting at the given offset.
     *
     * @param ab  the byte-array
     * @param of  the offset
     *
     * @return the long represented by the sequence of bytes
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is less than of + 8
     */
    public static long toLong(byte[] ab, int of)
        {
        long n1 = ((ab[of    ]       ) << 24)
                | ((ab[of + 1] & 0xFF) << 16)
                | ((ab[of + 2] & 0xFF) << 8 )
                | ((ab[of + 3] & 0xFF)      );
        long n2 = ((ab[of + 4]       ) << 24)
                | ((ab[of + 5] & 0xFF) << 16)
                | ((ab[of + 6] & 0xFF) << 8 )
                | ((ab[of + 7] & 0xFF)      );

        return (n1 << 32) | (n2 & 0xFFFFFFFFL);
        }

    /**
     * Return the long represented by the sequence of eight bytes (in big-endian
     * form) in the specified byte-array.
     *
     * @param ab  the byte-array
     *
     * @return the long represented by the byte-array
     *
     * @throws ArrayIndexOutOfBoundsException iff the length of the byte array
     *         is less than 8
     */
    public static long toLong(byte[] ab)
        {
        return toLong(ab, 0);
        }


    // ----- constants ------------------------------------------------------

    /**
    * Array that maps a byte value to a number of bits set in that byte.
    */
    private static final byte[] BIT_COUNT =
        {
        0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
        };

    /**
    * Array that maps a byte value to the bit position (0..7) of its most
    * significant bit.
    */
    private static final byte[] BIT_LEFTMOST =
        {
       -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
        4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        };

    /**
    * Array that maps a byte value to the bit position (0..7) of its least
    * significant bit.
    */
    private static final byte[] BIT_RIGHTMOST =
        {
       -1,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
        };
    }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy