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

net.algart.arrays.PackedBitArrays Maven / Gradle / Ivy

Go to download

Open-source Java libraries, supporting generalized smart arrays and matrices with elements of any types, including a wide set of 2D-, 3D- and multidimensional image processing and other algorithms, working with arrays and matrices.

The newest version!
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package net.algart.arrays;

import java.util.Objects;
import java.util.zip.CRC32;
import java.util.zip.Checksum;

/**
 * 

Operations with bit arrays packed into long[] Java arrays.

* *

AlgART bits arrays, created by {@link SimpleMemoryModel}, * are based on operations provided by this class.

* *

The maximal length of bit arrays supported by this class is 237-64. * All indexes and lengths passed to methods of this class must not exceed this value. * Moreover, all indexes and length, concerning usual (non-packed) Java array, * must not exceed 231-1. In another case, the results are unspecified. * ("Unspecified" means that any elements of the passed arrays can be read or changed, * or that IndexOutOfBoundsException can be thrown.)

* *

In all methods of this class, it's supposed that the bit #k in a packed long[] array * is the bit #(k%64) in the long element array[k/64]. * In other words, the bit #k * (false or true value) can be extracted by the following operator:

* *
 * (array[k >>> 6] & (1L << (k & 63))) != 0L
 * 
* *

and can be set or cleared by the following operators:

* *
 * if (newValue) // we need to set bit #k to 1
 *     array[k >>> 6] |= 1L << (k & 63);
 * else          // we need to clear bit #k to 0
 *     array[k >>> 6] &= ~(1L << (k & 63));
 * 
* *

You may use {@link #getBit(long[], long)} and {@link #setBit(long[], long, boolean)}, implementing * the equivalent code.

* *

If any method of this class modifies some portion of an element of a packed long[] Java array, * i.e. modifies less than all 64 its bits, then all accesses to this long element are performed * inside a single synchronized block, using the following instruction:

* *
 * synchronized (array) {
 *     // accessing to some element array[k]
 * }
 * 
* *

unless otherwise specified in the method comments. (See an example in comments to {@link #setBit} method.) * If all 64 bits of the element are written, or if the bits are read only, then no synchronization is performed. * Such behavior allows to simultaneously work with non-overlapping fragments of a packed bit array * from several threads (different fragments for different threads), as if it would be a usual Java array. * However, some methods of this class do not perform such synchronization; the names of all such methods has * ...NoSync postfix.

* *

This class cannot be instantiated.

* * @author Daniel Alievsky * @see PackedBitArraysPer8 * @see PackedBitBuffers */ public class PackedBitArrays { private PackedBitArrays() { } /** * Returns numberOfLongs << 6: the maximal number of bits that * can be stored in the specified number of long values. * * @param numberOfLongs number of packed long[] values. * @return 64 * numberOfLongs * @throws TooLargeArrayException if the argument is too large: ≥ 257. * @throws IllegalArgumentException if the argument is negative. */ public static long unpackedLength(long numberOfLongs) { if (numberOfLongs < 0) { throw new IllegalArgumentException("Negative packed length"); } if (numberOfLongs >= 1L << 57) { throw new TooLargeArrayException("Too large packed length: number of unpacked bits >= 2^63"); } return numberOfLongs << 6; } /** * Returns ((long) array.length) << 6: the maximal number of bits that * can be stored in the specified array. * * @param array long[] array. * @return 64 * (long) array.length * @throws NullPointerException if the argument is {@code null}. */ public static long unpackedLength(long[] array) { return ((long) array.length) << 6; } /** * Returns (numberOfBits + 63) >>> 6: the minimal number of long values * allowing to store the specified number of bits. * * @param numberOfBits the number of bits (the length of bit array). * @return (numberOfBits + 63) >>> 6 * (the length of corresponding long[] array). * @throws IllegalArgumentException if the argument is negative. */ public static long packedLength(long numberOfBits) { if (numberOfBits < 0) { throw new IllegalArgumentException("Negative unpacked length"); } return (numberOfBits + 63) >>> 6; // here >>> must be used instead of >>, because numberOfBits+63 can be >Long.MAX_VALUE } /** * Returns the same result as {@link #packedLength(long) packedLength(numberOfBits)} as * a 32-bit int value, or throws {@link TooLargeArrayException} if * that result is greater than Integer.MAX_VALUE. * * @param numberOfBits the number of bits (the length of bit array). * @return (numberOfBits + 63) >>> 6 * (the length of corresponding long[] array). * @throws IllegalArgumentException if the argument is negative. * @throws TooLargeArrayException if numberOfBits ≥ 237. */ public static int packedLength32(long numberOfBits) { if (numberOfBits < 0) { throw new IllegalArgumentException("Negative unpacked length"); } long result = (numberOfBits + 63) >>> 6; // here >>> must be used instead of >>, because numberOfBits+63 can be >Long.MAX_VALUE if (result > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large number of bits " + numberOfBits + ": number of packed longs " + result + " >= 2^31"); } return (int) result; } /** * Equivalent of {@link #packedLength32(long)} for int argument. * * @param numberOfBits the number of bits (the length of bit array). * @return (numberOfBits + 63) >>> 6 * (the length of corresponding long[] array). * @throws IllegalArgumentException if the argument is negative. */ public static int packedLength32(int numberOfBits) { if (numberOfBits < 0) { throw new IllegalArgumentException("Negative unpacked length"); } return (numberOfBits + 63) >>> 6; // here >>> must be used instead of >>, because numberOfBits+63 may be >Integer.MAX_VALUE } /** * Returns the bit #index in the packed src bit array. * Equivalent to the following expression:
     * (src[(int)(index >>> 6)] & (1L << (index & 63))) != 0L;
     * 
* * @param src the source array (bits are packed in long values). * @param index index of the returned bit. * @return the bit at the specified index. * @throws NullPointerException if src is {@code null}. * @throws IndexOutOfBoundsException if this method cause access of data outside array bounds. */ public static boolean getBit(long[] src, long index) { return (src[(int) (index >>> 6)] & (1L << (index & 63))) != 0L; } /** * Sets the bit #index in the packed dest bit array. * Equivalent to the following operators:
     * synchronized (dest) {
     *     if (value)
     *         dest[(int)(index >>> 6)] |= 1L << (index & 63);
     *     else
     *         dest[(int)(index >>> 6)] &= ~(1L << (index & 63));
     * }
     * 
* * @param dest the destination array (bits are packed in long values). * @param index index of the written bit. * @param value new bit value. * @throws NullPointerException if dest is {@code null}. * @throws IndexOutOfBoundsException if this method cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void setBit(long[] dest, long index, boolean value) { synchronized (dest) { if (value) dest[(int) (index >>> 6)] |= 1L << (index & 63); else dest[(int) (index >>> 6)] &= ~(1L << (index & 63)); } } /** * Sets the bit #index in the packed dest bit array without synchronization. * Equivalent to the following operators:
     *     if (value)
     *         dest[(int)(index >>> 6)] |= 1L << (index & 63);
     *     else
     *         dest[(int)(index >>> 6)] &= ~(1L << (index & 63));
     * }
     * 
* *

Note that this method is usually much faster than {@link #setBit(long[], long, boolean)}. * If you are not going to work with the same dest array from different threads, * you should prefer this method. * Also you may freely use this method if you are synchronizing all access to this array via some * form of external synchronization: in this case, no additional internal synchronization is needed. * (But remember: such external synchronization must be used on any access to this array, * not only when calling this method!)

* * @param dest the destination array (bits are packed in long values). * @param index index of the written bit. * @param value new bit value. * @throws NullPointerException if dest is {@code null}. * @throws IndexOutOfBoundsException if this method cause access of data outside array bounds. */ public static void setBitNoSync(long[] dest, long index, boolean value) { if (value) dest[(int) (index >>> 6)] |= 1L << (index & 63); else dest[(int) (index >>> 6)] &= ~(1L << (index & 63)); } /** * Returns the sequence of count bits (maximum 64 bits), starting from the bit #srcPos, * in the packed src bit array. * *

More precisely, the bit #(srcPos+k) will be returned in the bit #k of the returned * long value R: the first bit #srcPos will be equal to * R&1, the following bit #(srcPos+1) will be equal to * (R>>1)&1, etc. * If count=0, the result is 0.

* *

The same result can be calculated using the following loop * (for correct count in the range 0..64):

* *
     *      long result = 0;
     *      for (int k = 0; k < count; k++) {
     *          final long bit = {@link #getBit(long[], long) PackedBitArrays.getBit}(src, srcPos + k) ? 1L : 0L;
     *          result |= bit << k;
     *      }
* *

But this function works significantly faster, if count is greater than 1.

* *

Note: unlike the loop listed above, this function does not throw exception for too large indexes of bits * after the end of the array (≥64*src.length); instead, all bits outside the array are * considered to be zero. * (But negative indexes are not allowed.)

* * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be unpacked (must be in range 0..64). * @return the sequence of count bits. * @throws NullPointerException if src argument is {@code null}. * @throws IndexOutOfBoundsException if srcPos < 0 or * if copying would cause access of data outside array bounds. * @throws IllegalArgumentException if count < 0 or count > 64. */ public static long getBits64(long[] src, long srcPos, int count) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IndexOutOfBoundsException("Negative srcPos argument: " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count argument: " + count); } if (count > 64) { throw new IllegalArgumentException("Too large count argument: " + count + "; we cannot get > 64 bits in getBits64 method"); } return getBits64Impl(src, srcPos, count); } /** * Sets the sequence of count bits (maximum 64 bits), starting from the bit #destPos, * in the packed dest bit array. This is the reverse operation of * {@link #getBits64(long[], long, int)}. * *

This function is equivalent to the following loop * (for correct count in the range 0..64):

* *
     *      for (int k = 0; k < count; k++) {
     *          final long bit = (bits >>> k) & 1L;
     *          {@link #setBit(long[], long, boolean) PackedBitArrays.setBit}(dest, destPos + k, bit != 0);
     *      }
* *

But this function works significantly faster, if count is greater than 1.

* *

Note: unlike the loop listed above, this function does not throw exception for too large indexes of bits * after the end of the array (≥64*dest.length); instead, extra bits outside * the array are just ignored. * (But negative indexes are not allowed.)

* * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param bits sequence of new bits to be copied into the destination array. * @param count the number of bits to be written (must be in range 0..64). * @throws NullPointerException if dest argument is {@code null}. * @throws IndexOutOfBoundsException if destPos < 0 or * if copying would cause access of data outside array bounds. * @throws IllegalArgumentException if count < 0 or count > 64. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void setBits64(long[] dest, long destPos, long bits, int count) { Objects.requireNonNull(dest, "Null dest"); if (destPos < 0) { throw new IndexOutOfBoundsException("Negative destPos argument: " + destPos); } if (count < 0) { throw new IllegalArgumentException("Negative count argument: " + count); } if (count > 64) { throw new IllegalArgumentException("Too large count argument: " + count + "; we cannot set > 64 bits in setBits64 method"); } synchronized (dest) { setBits64Impl(dest, destPos, bits, count); } } /** * Sets the sequence of count bits (maximum 64 bits), starting from the bit #destPos, * in the packed dest bit array without synchronization. * May be used instead of {@link #setBits64(long[], long, long, int)}, if you are not planning to call * this method from different threads for the same dest array. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param bits sequence of new bits to be copied into the destination array. * @param count the number of bits to be written (must be in range 0..64). * @throws NullPointerException if dest argument is {@code null}. * @throws IndexOutOfBoundsException if destPos < 0 or * if copying would cause access of data outside array bounds. * @throws IllegalArgumentException if count < 0 or count > 64. */ public static void setBits64NoSync(long[] dest, long destPos, long bits, int count) { Objects.requireNonNull(dest, "Null dest"); if (destPos < 0) { throw new IndexOutOfBoundsException("Negative destPos argument: " + destPos); } if (count < 0) { throw new IllegalArgumentException("Negative count argument: " + count); } if (count > 64) { throw new IllegalArgumentException("Too large count argument: " + count + "; we cannot set > 64 bits in setBits64NoSync method"); } setBits64Impl(dest, destPos, bits, count); } /** * Returns a hash code based on the contents of the specified fragment of the given packed bit array. * If the passed array is {@code null} or fromIndex==toIndex, returns 0. * *

The returned hash code depends only on the sequence of packed bits, but does not depend * on the position of this sequence in the specified long[] array. * *

For any two packed bit arrays a1 and a2 such that * PackedBitArrays.bitEquals(a1, pos1, a2, pos2, count), it is also the case that * PackedBitArrays.bitHashCode(a1, pos1, pos1 + count) == * PackedBitArrays.bitHashCode(a2, pos2, pos2 + count). * * @param array the packed bit array whose content-based hash code to compute. * @param fromIndex the initial index of the checked fragment, inclusive. * @param toIndex the end index of the checked fragment, exclusive. * @return a content-based hash code for the specified fragment in array. * @throws IllegalArgumentException if the array argument is not a Java array. * @throws IndexOutOfBoundsException if fromIndex or toIndex are negative, * if toIndex is greater than array.length*64 * (0 if array==null), * or if fromIndex is greater than startIndex, * or if array==null and not fromIndex==toIndex==0 * @see #bitEquals(long[], long, long[], long, long) * @see JArrays#arrayHashCode(Object, int, int) */ public static int bitHashCode(long[] array, long fromIndex, long toIndex) { Checksum sum = new CRC32(); updateBitHashCode(array, fromIndex, toIndex, sum); return fromIndex == toIndex ? 0 : (int) sum.getValue(); } /** * Updates hash code (hash argument) on the base of the contents * of the specified fragment of the given packed bit array. * If the passed array is {@code null} or fromIndex==toIndex, does nothing. * *

This method is used by {@link #bitHashCode(long[], long, long) * bitHashCode(long[] array, long fromIndex, long toIndex)}. * More precisely, that method is equivalent to:

     * Checksum sum = new CRC32();
     * updateBitHashCode(array, fromIndex, toIndex, sum);
     * return fromIndex == toIndex ? 0 : (int)sum.getValue();
     * 
* *

The following 2 code fragment always produce the same results in hashargument:

     * updateBitHashCode(arr, fromIndex, toIndex, hash);
     * 
and
     * updateBitHashCode(arr, fromIndex, k1, hash);
     * updateBitHashCode(arr, k1, k2, hash);
     * ...
     * updateBitHashCode(arr, kN, toIndex, hash);
     * 
* where fromIndex <= k1 <= k2 <= ... <= kN <= toIndex. * So, unlike bitHashCode, this method allows to calculate correct hash code * of a long array when we cannot get all its element at the same time, * but can get sequent portions ot it. * * @param array the packed bit array whose content-based hash code to compute. * @param fromIndex the initial index of the checked fragment, inclusive. * @param toIndex the end index of the checked fragment, exclusive. * @param hash updated hash code. * @throws NullPointerException if array is {@code null}. * @throws IndexOutOfBoundsException if fromIndex or toIndex are negative, * if toIndex is greater than array.length * (0 if array==null), * or if fromIndex is greater than startIndex, * or if array==null and not fromIndex==toIndex==0 */ public static void updateBitHashCode(long[] array, long fromIndex, long toIndex, Checksum hash) { Objects.requireNonNull(hash, "Null hash argument"); if (fromIndex < 0) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: initial index = " + fromIndex); } if (fromIndex > toIndex) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: initial index = " + fromIndex + " > end index = " + toIndex); } if (array == null) { if (toIndex > 0) throw new ArrayIndexOutOfBoundsException("Bit array index out of range for null array: end index = " + toIndex); } else { if (toIndex > ((long) array.length) << 6) throw new ArrayIndexOutOfBoundsException("Bit array index out of range: end index = " + toIndex); } if (fromIndex == toIndex) { // in particular, if array == null return; } boolean[] bits = new boolean[4096]; // Important: we must produce the same hash code for every placement in the packed array! // So, good optimization, based on processing long values, is difficult here. for (long pos = fromIndex; pos < toIndex; pos += bits.length) { int len = (int) Math.min(bits.length, toIndex - pos); unpackBits(bits, 0, array, pos, len); JArrays.updateArrayHashCode(bits, 0, len, hash); } } /** * Returns true if the specified fragments of the given packed bit arrays are equals, * or if both arguments are {@code null}. * Returns false if one of the arguments is {@code null}, but the other is not {@code null}. * *

The two packed bit arrays are considered equal if all corresponding pairs of bits * in the two arrays are equal. * * @param array1 one array to be tested for equality. * @param pos1 the initial index of the checked fragment in the first array. * @param array2 the other array to be tested for equality. * @param pos2 the initial index of the checked fragment in the second array. * @param length the number of compared elements. * @return true if the specified fragments of two arrays are equal. * @throws IllegalArgumentException if the array1 or array2 argument is not * a Java array. * @throws IndexOutOfBoundsException if pos1, pos2 or length are negative, * if pos1 + length is greater than array1.length*64 * (0 if array1==null), * or if pos2 + length is greater than array2.length*64 * (0 if array2==null). */ public static boolean bitEquals(long[] array1, long pos1, long[] array2, long pos2, long length) { long length1 = array1 == null ? 0 : ((long) array1.length) << 6; long length2 = array2 == null ? 0 : ((long) array2.length) << 6; if (pos1 < 0) { throw new ArrayIndexOutOfBoundsException("Negative bit array initial index: pos1 = " + pos1); } if (pos2 < 0) { throw new ArrayIndexOutOfBoundsException("Negative bit array initial index: pos2 = " + pos2); } if (length < 0) { throw new ArrayIndexOutOfBoundsException("Negative number of compared elements: length = " + length); } if (pos1 + length > length1) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: pos1 + length = " + (pos1 + length)); } if (pos2 + length > length2) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: pos2 + length = " + (pos2 + length)); } if (array1 == array2) { return array1 == null || pos1 == pos2; } if (array1 == null || array2 == null) { return false; } if (length == 0) { return true; } if ((pos1 & 63) == (pos2 & 63)) { int first1 = (int) (pos1 >>> 6); int first2 = (int) (pos2 >>> 6); int last1 = (int) ((pos1 + length - 1) >>> 6); int last2 = (int) ((pos2 + length - 1) >>> 6); if (first1 == last1) { // so, length < 64 long mask = -(1L << (pos1 & 63)); // all bits pos1&63..63: correct even if (pos1&63)==0 // here pos1 + length > 0: it can be zero only if length==0, that was checked above int ofs = (int) ((pos1 + length) & 63); if (ofs != 0) mask &= (1L << ofs) - 1; // all bits 0..((pos1&63)+length)-1: incorrect if (pos1&63)+length==64 return (array1[first1] & mask) == (array2[first2] & mask); } if ((pos1 & 63) != 0) { long fromMask = -(1L << (pos1 & 63)); // all bits pos1&63..63 if ((array1[first1] & fromMask) != (array2[first2] & fromMask)) { return false; } first1++; first2++; } if (((pos1 + length) & 63) != 0) { long toMask = (1L << ((pos1 + length) & 63)) - 1; // all bits 0..((pos1+length)&63)-1 if ((array1[last1] & toMask) != (array2[last2] & toMask)) { return false; } last1--; // last2--; // - will not be used } if (first1 <= last1) { return JArrays.arrayEquals(array1, first1, array2, first2, last1 - first1 + 1); } return true; } else { for (long pos1Max = pos1 + length; pos1 < pos1Max; pos1++, pos2++) { if (((array1[(int) (pos1 >>> 6)] >>> (pos1 & 63)) & 1L) != ((array2[(int) (pos2 >>> 6)] >>> (pos2 & 63)) & 1L)) { return false; } } return true; } } /*Repeat.SectionStart copyBits*/ /** * Copies count bits, packed in src array, starting from the bit #srcPos, * to packed dest array, starting from the bit #destPos. * *

This method works correctly even if src == dest * and the copied areas overlap, * i.e. if Math.abs(destPos - srcPos) < count. * More precisely, in this case the copying is performed as if the * bits at positions srcPos..srcPos+count-1 * were first unpacked to a temporary boolean[] array with count elements * and then the contents of the temporary array were packed into positions * destPos..destPos+count-1. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be copied (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void copyBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart copyBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } //Start_reverseOrder !! this comment is necessary for preprocessing by Repeater !! if (src == dest && srcPos <= destPos && srcPos + count > destPos) //End_reverseOrder !! this comment is necessary for preprocessing by Repeater !! { // overlap possible if (sPosRem == dPosRem) { //Start_nothingToDo !! this comment is necessary for preprocessing by Repeater !! if (sPos == dPos) { return; // nothing to do } //End_nothingToDo !! this comment is necessary for preprocessing by Repeater !! final int sPosStart = sPos; final int dPosStart = dPos; if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end count -= cntStart; dPos++; sPos++; } int cnt = (int) (count >>> 6); int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos + cnt] = (src[sPos + cnt] & maskFinish) | (dest[dPos + cnt] & ~maskFinish); } } System.arraycopy(src, sPos, dest, dPos, cnt); if (cntStart > 0) { synchronized (dest) { dest[dPosStart] = (src[sPosStart] & maskStart) | (dest[dPosStart] & ~maskStart); } } } else { final int shift = dPosRem - sPosRem; final int sPosStart = sPos; final int dPosStart = dPos; final int sPosRemStart = sPosRem; if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element sPosRem += cntStart; } else { sPos++; sPosRem = (sPosRem + cntStart) & 63; } // we suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more count -= cntStart; dPos++; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] int cnt = (int) (count >>> 6); final long dPosMin = dPos; sPos += cnt; dPos += cnt; int cntFinish = (int) (count & 63); final int sPosRem64 = 64 - sPosRem; long sPrev; if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = (sPrev = src[sPos]) >>> sPosRem; } else { v = ((sPrev = src[sPos]) >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = (v & maskFinish) | (dest[dPos] & ~maskFinish); } } else { //Start_sPrev !! this comment is necessary for preprocessing by Repeater !! sPrev = src[sPos]; // IndexOutOfBoundException is impossible here, because there is one of the following situations: // 1) cnt > 0, then src[sPos] is really necessary in the following loop; // 2) cnt == 0 and cntStart > 0, then src[sPos] will be necessary for making dest[dPosStart]. // All other situations are impossible here: // 3) cntFinish > 0: it was processed above in "if (cntFinish > 0)..." branch; // 4) cntStart == 0, cntFinish == 0 and cnt == 0, i.e. count == 0: it's impossible // in this branch of all algorithm (overlap is impossible when count == 0). //End_sPrev !! this comment is necessary for preprocessing by Repeater !! } while (dPos > dPosMin) { // cnt times --sPos; --dPos; dest[dPos] = (sPrev << sPosRem64) | ((sPrev = src[sPos]) >>> sPosRem); } if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end long v; if (sPosRemStart + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = src[sPosStart] << shift; else v = src[sPosStart] >>> -shift; } else { v = (src[sPosStart] >>> -shift) | (src[sPosStart + 1] << (64 + shift)); } synchronized (dest) { dest[dPosStart] = (v & maskStart) | (dest[dPosStart] & ~maskStart); } } } } else { // usual case if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] = (src[sPos] & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; dPos++; sPos++; } int cnt = (int) (count >>> 6); System.arraycopy(src, sPos, dest, dPos, cnt); sPos += cnt; dPos += cnt; int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = (src[sPos] & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] = (v & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] = (sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = (v & maskFinish) | (dest[dPos] & ~maskFinish); } } } } //[[Repeat.SectionEnd copyBits_method_impl]] } /** * Equivalent to {@link #copyBits(long[], long, long[], long, long)} method with the only exception, * that this method does not perform synchronization on dest array. * You may use this method instead of {@link #copyBits}, * if you are not planning to call it from different threads for the same dest array. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be copied (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void copyBitsNoSync(long[] dest, long destPos, long[] src, long srcPos, long count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } //Start_reverseOrder !! this comment is necessary for preprocessing by Repeater !! if (src == dest && srcPos <= destPos && srcPos + count > destPos) //End_reverseOrder !! this comment is necessary for preprocessing by Repeater !! { // overlap possible if (sPosRem == dPosRem) { //Start_nothingToDo !! this comment is necessary for preprocessing by Repeater !! if (sPos == dPos) { return; // nothing to do } //End_nothingToDo !! this comment is necessary for preprocessing by Repeater !! final int sPosStart = sPos; final int dPosStart = dPos; if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end count -= cntStart; dPos++; sPos++; } int cnt = (int) (count >>> 6); int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) dest[dPos + cnt] = (src[sPos + cnt] & maskFinish) | (dest[dPos + cnt] & ~maskFinish); } System.arraycopy(src, sPos, dest, dPos, cnt); if (cntStart > 0) { dest[dPosStart] = (src[sPosStart] & maskStart) | (dest[dPosStart] & ~maskStart); } } else { final int shift = dPosRem - sPosRem; final int sPosStart = sPos; final int dPosStart = dPos; final int sPosRemStart = sPosRem; if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element sPosRem += cntStart; } else { sPos++; sPosRem = (sPosRem + cntStart) & 63; } // we suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more count -= cntStart; dPos++; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] int cnt = (int) (count >>> 6); final long dPosMin = dPos; sPos += cnt; dPos += cnt; int cntFinish = (int) (count & 63); final int sPosRem64 = 64 - sPosRem; long sPrev; if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = (sPrev = src[sPos]) >>> sPosRem; } else { v = ((sPrev = src[sPos]) >>> sPosRem) | (src[sPos + 1] << sPosRem64); } dest[dPos] = (v & maskFinish) | (dest[dPos] & ~maskFinish); } else { //Start_sPrev !! this comment is necessary for preprocessing by Repeater !! sPrev = src[sPos]; // IndexOutOfBoundException is impossible here, because there is one of the following situations: // 1) cnt > 0, then src[sPos] is really necessary in the following loop; // 2) cnt == 0 and cntStart > 0, then src[sPos] will be necessary for making dest[dPosStart]. // All other situations are impossible here: // 3) cntFinish > 0: it was processed above in "if (cntFinish > 0)..." branch; // 4) cntStart == 0, cntFinish == 0 and cnt == 0, i.e. count == 0: it's impossible // in this branch of all algorithm (overlap is impossible when count == 0). //End_sPrev !! this comment is necessary for preprocessing by Repeater !! } while (dPos > dPosMin) { // cnt times --sPos; --dPos; dest[dPos] = (sPrev << sPosRem64) | ((sPrev = src[sPos]) >>> sPosRem); } if (cntStart > 0) { // here we correct indexes only: we delay actual access until the end long v; if (sPosRemStart + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = src[sPosStart] << shift; else v = src[sPosStart] >>> -shift; } else { v = (src[sPosStart] >>> -shift) | (src[sPosStart + 1] << (64 + shift)); } dest[dPosStart] = (v & maskStart) | (dest[dPosStart] & ~maskStart); } } } else { // usual case if (sPosRem == dPosRem) { if (cntStart > 0) { dest[dPos] = (src[sPos] & maskStart) | (dest[dPos] & ~maskStart); count -= cntStart; dPos++; sPos++; } int cnt = (int) (count >>> 6); System.arraycopy(src, sPos, dest, dPos, cnt); sPos += cnt; dPos += cnt; int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) dest[dPos] = (src[sPos] & maskFinish) | (dest[dPos] & ~maskFinish); } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more dest[dPos] = (v & maskStart) | (dest[dPos] & ~maskStart); count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] = (sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } dest[dPos] = (v & maskFinish) | (dest[dPos] & ~maskFinish); } } } } /*Repeat.SectionEnd copyBits*/ /** * Packs count bits from the src array, starting from the element #srcPos, * into a newly created packed bit array long[{@link #packedLength(long) packedLength}(count)] * returned as a result, starting from the bit #0. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #packBits(long[], long, boolean[], int, int)} * method.

* *

Note: srcPos and count arguments are declared as long, * but actually they must be in 0..Integer.MAX_VALUE range; in another case, * this method throws IllegalArgumentException. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (unpacked boolean values). * @param srcPos position of the first bit read in the source array * (must be in 0..Integer.MAX_VALUE range). * @param count the number of bits to be packed * (must be in 0..Integer.MAX_VALUE range). * @return the result bit array, where bits are packed in long. * @throws NullPointerException if src is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. */ public static long[] packBits(boolean[] src, long srcPos, long count) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (srcPos > src.length) { throw new IllegalArgumentException("The source position " + srcPos + " is out of the array boolean[" + src.length + "]"); } if (count > src.length - srcPos) { throw new IllegalArgumentException("Too short source array boolean[" + src.length + "]: it does not contain " + count + " bits since position " + srcPos); } assert count == (int) count; final long[] dest = new long[(int) packedLength(count)]; int sPos = (int) srcPos; final int cnt = (int) count >>> 6; for (int k = 0; k < cnt; k++) { int low = (src[sPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[sPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[sPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[sPos + 2] ? 1 << 2 : 0) | (src[sPos + 3] ? 1 << 3 : 0) | (src[sPos + 4] ? 1 << 4 : 0) | (src[sPos + 5] ? 1 << 5 : 0) | (src[sPos + 6] ? 1 << 6 : 0) | (src[sPos + 7] ? 1 << 7 : 0) | (src[sPos + 8] ? 1 << 8 : 0) | (src[sPos + 9] ? 1 << 9 : 0) | (src[sPos + 10] ? 1 << 10 : 0) | (src[sPos + 11] ? 1 << 11 : 0) | (src[sPos + 12] ? 1 << 12 : 0) | (src[sPos + 13] ? 1 << 13 : 0) | (src[sPos + 14] ? 1 << 14 : 0) | (src[sPos + 15] ? 1 << 15 : 0) | (src[sPos + 16] ? 1 << 16 : 0) | (src[sPos + 17] ? 1 << 17 : 0) | (src[sPos + 18] ? 1 << 18 : 0) | (src[sPos + 19] ? 1 << 19 : 0) | (src[sPos + 20] ? 1 << 20 : 0) | (src[sPos + 21] ? 1 << 21 : 0) | (src[sPos + 22] ? 1 << 22 : 0) | (src[sPos + 23] ? 1 << 23 : 0) | (src[sPos + 24] ? 1 << 24 : 0) | (src[sPos + 25] ? 1 << 25 : 0) | (src[sPos + 26] ? 1 << 26 : 0) | (src[sPos + 27] ? 1 << 27 : 0) | (src[sPos + 28] ? 1 << 28 : 0) | (src[sPos + 29] ? 1 << 29 : 0) | (src[sPos + 30] ? 1 << 30 : 0) | (src[sPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; sPos += 32; int high = (src[sPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[sPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[sPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[sPos + 2] ? 1 << 2 : 0) | (src[sPos + 3] ? 1 << 3 : 0) | (src[sPos + 4] ? 1 << 4 : 0) | (src[sPos + 5] ? 1 << 5 : 0) | (src[sPos + 6] ? 1 << 6 : 0) | (src[sPos + 7] ? 1 << 7 : 0) | (src[sPos + 8] ? 1 << 8 : 0) | (src[sPos + 9] ? 1 << 9 : 0) | (src[sPos + 10] ? 1 << 10 : 0) | (src[sPos + 11] ? 1 << 11 : 0) | (src[sPos + 12] ? 1 << 12 : 0) | (src[sPos + 13] ? 1 << 13 : 0) | (src[sPos + 14] ? 1 << 14 : 0) | (src[sPos + 15] ? 1 << 15 : 0) | (src[sPos + 16] ? 1 << 16 : 0) | (src[sPos + 17] ? 1 << 17 : 0) | (src[sPos + 18] ? 1 << 18 : 0) | (src[sPos + 19] ? 1 << 19 : 0) | (src[sPos + 20] ? 1 << 20 : 0) | (src[sPos + 21] ? 1 << 21 : 0) | (src[sPos + 22] ? 1 << 22 : 0) | (src[sPos + 23] ? 1 << 23 : 0) | (src[sPos + 24] ? 1 << 24 : 0) | (src[sPos + 25] ? 1 << 25 : 0) | (src[sPos + 26] ? 1 << 26 : 0) | (src[sPos + 27] ? 1 << 27 : 0) | (src[sPos + 28] ? 1 << 28 : 0) | (src[sPos + 29] ? 1 << 29 : 0) | (src[sPos + 30] ? 1 << 30 : 0) | (src[sPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; sPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); } int countFinish = (int) count & 63; for (int k = 0; k < countFinish; sPos++, k++) { if (src[sPos]) { dest[cnt] |= 1L << k; } else { dest[cnt] &= ~(1L << k); } } return dest; } /** * Packs count bits from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked boolean values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBits(long[] dest, long destPos, boolean[] src, int srcPos, int count) { //[[Repeat.SectionStart packBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 1 << 2 : 0) | (src[srcPos + 3] ? 1 << 3 : 0) | (src[srcPos + 4] ? 1 << 4 : 0) | (src[srcPos + 5] ? 1 << 5 : 0) | (src[srcPos + 6] ? 1 << 6 : 0) | (src[srcPos + 7] ? 1 << 7 : 0) | (src[srcPos + 8] ? 1 << 8 : 0) | (src[srcPos + 9] ? 1 << 9 : 0) | (src[srcPos + 10] ? 1 << 10 : 0) | (src[srcPos + 11] ? 1 << 11 : 0) | (src[srcPos + 12] ? 1 << 12 : 0) | (src[srcPos + 13] ? 1 << 13 : 0) | (src[srcPos + 14] ? 1 << 14 : 0) | (src[srcPos + 15] ? 1 << 15 : 0) | (src[srcPos + 16] ? 1 << 16 : 0) | (src[srcPos + 17] ? 1 << 17 : 0) | (src[srcPos + 18] ? 1 << 18 : 0) | (src[srcPos + 19] ? 1 << 19 : 0) | (src[srcPos + 20] ? 1 << 20 : 0) | (src[srcPos + 21] ? 1 << 21 : 0) | (src[srcPos + 22] ? 1 << 22 : 0) | (src[srcPos + 23] ? 1 << 23 : 0) | (src[srcPos + 24] ? 1 << 24 : 0) | (src[srcPos + 25] ? 1 << 25 : 0) | (src[srcPos + 26] ? 1 << 26 : 0) | (src[srcPos + 27] ? 1 << 27 : 0) | (src[srcPos + 28] ? 1 << 28 : 0) | (src[srcPos + 29] ? 1 << 29 : 0) | (src[srcPos + 30] ? 1 << 30 : 0) | (src[srcPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 1 << 2 : 0) | (src[srcPos + 3] ? 1 << 3 : 0) | (src[srcPos + 4] ? 1 << 4 : 0) | (src[srcPos + 5] ? 1 << 5 : 0) | (src[srcPos + 6] ? 1 << 6 : 0) | (src[srcPos + 7] ? 1 << 7 : 0) | (src[srcPos + 8] ? 1 << 8 : 0) | (src[srcPos + 9] ? 1 << 9 : 0) | (src[srcPos + 10] ? 1 << 10 : 0) | (src[srcPos + 11] ? 1 << 11 : 0) | (src[srcPos + 12] ? 1 << 12 : 0) | (src[srcPos + 13] ? 1 << 13 : 0) | (src[srcPos + 14] ? 1 << 14 : 0) | (src[srcPos + 15] ? 1 << 15 : 0) | (src[srcPos + 16] ? 1 << 16 : 0) | (src[srcPos + 17] ? 1 << 17 : 0) | (src[srcPos + 18] ? 1 << 18 : 0) | (src[srcPos + 19] ? 1 << 19 : 0) | (src[srcPos + 20] ? 1 << 20 : 0) | (src[srcPos + 21] ? 1 << 21 : 0) | (src[srcPos + 22] ? 1 << 22 : 0) | (src[srcPos + 23] ? 1 << 23 : 0) | (src[srcPos + 24] ? 1 << 24 : 0) | (src[srcPos + 25] ? 1 << 25 : 0) | (src[srcPos + 26] ? 1 << 26 : 0) | (src[srcPos + 27] ? 1 << 27 : 0) | (src[srcPos + 28] ? 1 << 28 : 0) | (src[srcPos + 29] ? 1 << 29 : 0) | (src[srcPos + 30] ? 1 << 30 : 0) | (src[srcPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } //[[Repeat.SectionEnd packBits_method_impl]] } /** * Packs count inverted bits from src array, starting from the element * #srcPos, to packed dest array, starting from the bit #destPos. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked inverted boolean values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsInverted(long[] dest, long destPos, boolean[] src, int srcPos, int count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); else dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] ? 0 : 1) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 0 : 1 << $INDEX(start=2)) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 0 : 1 << 1) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 0 : 1 << 2) | (src[srcPos + 3] ? 0 : 1 << 3) | (src[srcPos + 4] ? 0 : 1 << 4) | (src[srcPos + 5] ? 0 : 1 << 5) | (src[srcPos + 6] ? 0 : 1 << 6) | (src[srcPos + 7] ? 0 : 1 << 7) | (src[srcPos + 8] ? 0 : 1 << 8) | (src[srcPos + 9] ? 0 : 1 << 9) | (src[srcPos + 10] ? 0 : 1 << 10) | (src[srcPos + 11] ? 0 : 1 << 11) | (src[srcPos + 12] ? 0 : 1 << 12) | (src[srcPos + 13] ? 0 : 1 << 13) | (src[srcPos + 14] ? 0 : 1 << 14) | (src[srcPos + 15] ? 0 : 1 << 15) | (src[srcPos + 16] ? 0 : 1 << 16) | (src[srcPos + 17] ? 0 : 1 << 17) | (src[srcPos + 18] ? 0 : 1 << 18) | (src[srcPos + 19] ? 0 : 1 << 19) | (src[srcPos + 20] ? 0 : 1 << 20) | (src[srcPos + 21] ? 0 : 1 << 21) | (src[srcPos + 22] ? 0 : 1 << 22) | (src[srcPos + 23] ? 0 : 1 << 23) | (src[srcPos + 24] ? 0 : 1 << 24) | (src[srcPos + 25] ? 0 : 1 << 25) | (src[srcPos + 26] ? 0 : 1 << 26) | (src[srcPos + 27] ? 0 : 1 << 27) | (src[srcPos + 28] ? 0 : 1 << 28) | (src[srcPos + 29] ? 0 : 1 << 29) | (src[srcPos + 30] ? 0 : 1 << 30) | (src[srcPos + 31] ? 0 : 0x80000000) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] ? 0 : 1) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 0 : 1 << $INDEX(start=2)) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 0 : 1 << 1) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 0 : 1 << 2) | (src[srcPos + 3] ? 0 : 1 << 3) | (src[srcPos + 4] ? 0 : 1 << 4) | (src[srcPos + 5] ? 0 : 1 << 5) | (src[srcPos + 6] ? 0 : 1 << 6) | (src[srcPos + 7] ? 0 : 1 << 7) | (src[srcPos + 8] ? 0 : 1 << 8) | (src[srcPos + 9] ? 0 : 1 << 9) | (src[srcPos + 10] ? 0 : 1 << 10) | (src[srcPos + 11] ? 0 : 1 << 11) | (src[srcPos + 12] ? 0 : 1 << 12) | (src[srcPos + 13] ? 0 : 1 << 13) | (src[srcPos + 14] ? 0 : 1 << 14) | (src[srcPos + 15] ? 0 : 1 << 15) | (src[srcPos + 16] ? 0 : 1 << 16) | (src[srcPos + 17] ? 0 : 1 << 17) | (src[srcPos + 18] ? 0 : 1 << 18) | (src[srcPos + 19] ? 0 : 1 << 19) | (src[srcPos + 20] ? 0 : 1 << 20) | (src[srcPos + 21] ? 0 : 1 << 21) | (src[srcPos + 22] ? 0 : 1 << 22) | (src[srcPos + 23] ? 0 : 1 << 23) | (src[srcPos + 24] ? 0 : 1 << 24) | (src[srcPos + 25] ? 0 : 1 << 25) | (src[srcPos + 26] ? 0 : 1 << 26) | (src[srcPos + 27] ? 0 : 1 << 27) | (src[srcPos + 28] ? 0 : 1 << 28) | (src[srcPos + 29] ? 0 : 1 << 29) | (src[srcPos + 30] ? 0 : 1 << 30) | (src[srcPos + 31] ? 0 : 0x80000000) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); else dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); } } } } /** * Equivalent to {@link #packBits(long[], long, boolean[], int, int)} * method with the only exception, * that this method does not perform synchronization on dest array. * You may use this method instead of {@link #packBits(long[], long, boolean[], int, int)}, * if you are not planning to call it from different threads for the same dest array. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked boolean values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void packBitsNoSync(long[] dest, long destPos, boolean[] src, int srcPos, int count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 1 << 2 : 0) | (src[srcPos + 3] ? 1 << 3 : 0) | (src[srcPos + 4] ? 1 << 4 : 0) | (src[srcPos + 5] ? 1 << 5 : 0) | (src[srcPos + 6] ? 1 << 6 : 0) | (src[srcPos + 7] ? 1 << 7 : 0) | (src[srcPos + 8] ? 1 << 8 : 0) | (src[srcPos + 9] ? 1 << 9 : 0) | (src[srcPos + 10] ? 1 << 10 : 0) | (src[srcPos + 11] ? 1 << 11 : 0) | (src[srcPos + 12] ? 1 << 12 : 0) | (src[srcPos + 13] ? 1 << 13 : 0) | (src[srcPos + 14] ? 1 << 14 : 0) | (src[srcPos + 15] ? 1 << 15 : 0) | (src[srcPos + 16] ? 1 << 16 : 0) | (src[srcPos + 17] ? 1 << 17 : 0) | (src[srcPos + 18] ? 1 << 18 : 0) | (src[srcPos + 19] ? 1 << 19 : 0) | (src[srcPos + 20] ? 1 << 20 : 0) | (src[srcPos + 21] ? 1 << 21 : 0) | (src[srcPos + 22] ? 1 << 22 : 0) | (src[srcPos + 23] ? 1 << 23 : 0) | (src[srcPos + 24] ? 1 << 24 : 0) | (src[srcPos + 25] ? 1 << 25 : 0) | (src[srcPos + 26] ? 1 << 26 : 0) | (src[srcPos + 27] ? 1 << 27 : 0) | (src[srcPos + 28] ? 1 << 28 : 0) | (src[srcPos + 29] ? 1 << 29 : 0) | (src[srcPos + 30] ? 1 << 30 : 0) | (src[srcPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() \([^\)]*\) ==> (src[srcPos + $INDEX(start=2)] ? 1 << $INDEX(start=2) : 0) ,, ...(30);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] | (src[srcPos + 1] ? 1 << 1 : 0) //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] | (src[srcPos + 2] ? 1 << 2 : 0) | (src[srcPos + 3] ? 1 << 3 : 0) | (src[srcPos + 4] ? 1 << 4 : 0) | (src[srcPos + 5] ? 1 << 5 : 0) | (src[srcPos + 6] ? 1 << 6 : 0) | (src[srcPos + 7] ? 1 << 7 : 0) | (src[srcPos + 8] ? 1 << 8 : 0) | (src[srcPos + 9] ? 1 << 9 : 0) | (src[srcPos + 10] ? 1 << 10 : 0) | (src[srcPos + 11] ? 1 << 11 : 0) | (src[srcPos + 12] ? 1 << 12 : 0) | (src[srcPos + 13] ? 1 << 13 : 0) | (src[srcPos + 14] ? 1 << 14 : 0) | (src[srcPos + 15] ? 1 << 15 : 0) | (src[srcPos + 16] ? 1 << 16 : 0) | (src[srcPos + 17] ? 1 << 17 : 0) | (src[srcPos + 18] ? 1 << 18 : 0) | (src[srcPos + 19] ? 1 << 19 : 0) | (src[srcPos + 20] ? 1 << 20 : 0) | (src[srcPos + 21] ? 1 << 21 : 0) | (src[srcPos + 22] ? 1 << 22 : 0) | (src[srcPos + 23] ? 1 << 23 : 0) | (src[srcPos + 24] ? 1 << 24 : 0) | (src[srcPos + 25] ? 1 << 25 : 0) | (src[srcPos + 26] ? 1 << 26 : 0) | (src[srcPos + 27] ? 1 << 27 : 0) | (src[srcPos + 28] ? 1 << 28 : 0) | (src[srcPos + 29] ? 1 << 29 : 0) | (src[srcPos + 30] ? 1 << 30 : 0) | (src[srcPos + 31] ? 0x80000000 : 0) //[[Repeat.AutoGeneratedEnd]] // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos]) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } /*Repeat() char(\s+threshold) ==> int$1,,int$1,,int$1,,long$1,,float$1,,double$1;; char ==> byte,,short,,int,,long,,float,,double;; (src\[[^]]*])(?!\<\/code) ==> ($1 & 0xFF),,($1 & 0xFFFF),,$1,,... */ /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked char values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, char[] src, int srcPos, int count, char threshold) { //[[Repeat(INCLUDE_FROM_FILE, THIS_FILE, packBits_method_impl) // (src\[.*?]) ==> $1 > threshold !! Auto-generated: NOT EDIT !! ]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } //[[Repeat.IncludeEnd]] } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked char values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, char[] src, int srcPos, int count, char threshold) { //[[Repeat(INCLUDE_FROM_FILE, THIS_FILE, packBits_method_impl) // (src\[.*?]) ==> $1 < threshold !! Auto-generated: NOT EDIT !! ]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } //[[Repeat.IncludeEnd]] } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked char values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, char[] src, int srcPos, int count, char threshold) { //[[Repeat(INCLUDE_FROM_FILE, THIS_FILE, packBits_method_impl) // (src\[.*?]) ==> $1 >= threshold !! Auto-generated: NOT EDIT !! ]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } //[[Repeat.IncludeEnd]] } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked char values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, char[] src, int srcPos, int count, char threshold) { //[[Repeat(INCLUDE_FROM_FILE, THIS_FILE, packBits_method_impl) // (src\[.*?]) ==> $1 <= threshold !! Auto-generated: NOT EDIT !! ]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } //[[Repeat.IncludeEnd]] } /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */ /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFF) > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, byte[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFF) > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) > threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) > threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) > threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) > threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) > threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) > threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) > threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) > threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) > threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) > threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) > threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) > threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) > threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) > threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) > threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) > threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) > threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) > threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) > threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) > threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) > threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) > threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) > threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) > threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) > threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) > threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) > threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) > threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) > threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) > threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFF) > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) > threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) > threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) > threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) > threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) > threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) > threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) > threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) > threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) > threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) > threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) > threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) > threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) > threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) > threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) > threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) > threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) > threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) > threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) > threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) > threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) > threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) > threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) > threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) > threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) > threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) > threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) > threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) > threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) > threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) > threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFF) < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, byte[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFF) < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) < threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) < threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) < threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) < threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) < threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) < threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) < threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) < threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) < threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) < threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) < threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) < threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) < threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) < threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) < threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) < threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) < threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) < threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) < threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) < threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) < threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) < threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) < threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) < threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) < threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) < threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) < threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) < threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) < threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) < threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFF) < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) < threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) < threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) < threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) < threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) < threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) < threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) < threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) < threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) < threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) < threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) < threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) < threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) < threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) < threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) < threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) < threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) < threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) < threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) < threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) < threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) < threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) < threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) < threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) < threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) < threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) < threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) < threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) < threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) < threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) < threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFF) >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, byte[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFF) >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) >= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) >= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) >= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) >= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) >= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) >= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) >= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) >= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) >= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) >= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) >= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) >= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) >= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) >= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) >= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) >= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) >= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) >= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) >= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) >= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) >= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) >= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) >= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) >= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) >= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) >= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) >= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) >= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) >= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) >= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFF) >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) >= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) >= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) >= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) >= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) >= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) >= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) >= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) >= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) >= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) >= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) >= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) >= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) >= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) >= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) >= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) >= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) >= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) >= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) >= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) >= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) >= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) >= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) >= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) >= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) >= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) >= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) >= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) >= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) >= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) >= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFF) <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, byte[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFF) <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) <= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) <= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) <= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) <= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) <= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) <= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) <= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) <= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) <= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) <= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) <= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) <= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) <= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) <= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) <= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) <= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) <= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) <= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) <= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) <= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) <= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) <= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) <= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) <= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) <= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) <= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) <= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) <= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) <= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) <= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFF) <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFF) <= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFF) <= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFF) <= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFF) <= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFF) <= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFF) <= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFF) <= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFF) <= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFF) <= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFF) <= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFF) <= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFF) <= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFF) <= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFF) <= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFF) <= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFF) <= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFF) <= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFF) <= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFF) <= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFF) <= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFF) <= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFF) <= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFF) <= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFF) <= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFF) <= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFF) <= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFF) <= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFF) <= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFF) <= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFF) <= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFF) <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFF) <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFFFF) > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked short values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, short[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFFFF) > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) > threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) > threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) > threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) > threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) > threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) > threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) > threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) > threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) > threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) > threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) > threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) > threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) > threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) > threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) > threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) > threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) > threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) > threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) > threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) > threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) > threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) > threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) > threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) > threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) > threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) > threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) > threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) > threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) > threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) > threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFFFF) > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) > threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) > threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) > threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) > threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) > threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) > threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) > threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) > threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) > threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) > threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) > threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) > threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) > threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) > threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) > threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) > threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) > threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) > threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) > threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) > threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) > threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) > threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) > threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) > threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) > threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) > threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) > threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) > threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) > threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) > threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFFFF) < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked short values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, short[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFFFF) < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) < threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) < threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) < threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) < threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) < threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) < threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) < threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) < threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) < threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) < threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) < threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) < threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) < threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) < threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) < threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) < threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) < threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) < threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) < threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) < threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) < threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) < threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) < threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) < threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) < threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) < threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) < threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) < threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) < threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) < threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFFFF) < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) < threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) < threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) < threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) < threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) < threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) < threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) < threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) < threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) < threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) < threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) < threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) < threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) < threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) < threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) < threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) < threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) < threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) < threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) < threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) < threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) < threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) < threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) < threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) < threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) < threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) < threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) < threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) < threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) < threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) < threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFFFF) >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked short values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, short[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFFFF) >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) >= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) >= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) >= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) >= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) >= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) >= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) >= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) >= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) >= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) >= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) >= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) >= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) >= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) >= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) >= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) >= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) >= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) >= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) >= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) >= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) >= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) >= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) >= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) >= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) >= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) >= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) >= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) >= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) >= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) >= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFFFF) >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) >= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) >= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) >= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) >= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) >= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) >= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) >= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) >= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) >= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) >= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) >= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) >= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) >= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) >= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) >= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) >= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) >= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) >= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) >= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) >= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) >= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) >= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) >= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) >= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) >= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) >= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) >= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) >= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) >= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) >= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code (src[k] & 0xFFFF) <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked short values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, short[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = ((src[srcPos] & 0xFFFF) <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) <= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) <= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) <= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) <= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) <= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) <= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) <= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) <= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) <= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) <= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) <= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) <= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) <= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) <= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) <= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) <= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) <= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) <= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) <= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) <= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) <= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) <= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) <= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) <= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) <= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) <= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) <= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) <= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) <= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) <= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = ((src[srcPos] & 0xFFFF) <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | ((src[srcPos + 1] & 0xFFFF) <= threshold ? 1 << 1 : 0) | ((src[srcPos + 2] & 0xFFFF) <= threshold ? 1 << 2 : 0) | ((src[srcPos + 3] & 0xFFFF) <= threshold ? 1 << 3 : 0) | ((src[srcPos + 4] & 0xFFFF) <= threshold ? 1 << 4 : 0) | ((src[srcPos + 5] & 0xFFFF) <= threshold ? 1 << 5 : 0) | ((src[srcPos + 6] & 0xFFFF) <= threshold ? 1 << 6 : 0) | ((src[srcPos + 7] & 0xFFFF) <= threshold ? 1 << 7 : 0) | ((src[srcPos + 8] & 0xFFFF) <= threshold ? 1 << 8 : 0) | ((src[srcPos + 9] & 0xFFFF) <= threshold ? 1 << 9 : 0) | ((src[srcPos + 10] & 0xFFFF) <= threshold ? 1 << 10 : 0) | ((src[srcPos + 11] & 0xFFFF) <= threshold ? 1 << 11 : 0) | ((src[srcPos + 12] & 0xFFFF) <= threshold ? 1 << 12 : 0) | ((src[srcPos + 13] & 0xFFFF) <= threshold ? 1 << 13 : 0) | ((src[srcPos + 14] & 0xFFFF) <= threshold ? 1 << 14 : 0) | ((src[srcPos + 15] & 0xFFFF) <= threshold ? 1 << 15 : 0) | ((src[srcPos + 16] & 0xFFFF) <= threshold ? 1 << 16 : 0) | ((src[srcPos + 17] & 0xFFFF) <= threshold ? 1 << 17 : 0) | ((src[srcPos + 18] & 0xFFFF) <= threshold ? 1 << 18 : 0) | ((src[srcPos + 19] & 0xFFFF) <= threshold ? 1 << 19 : 0) | ((src[srcPos + 20] & 0xFFFF) <= threshold ? 1 << 20 : 0) | ((src[srcPos + 21] & 0xFFFF) <= threshold ? 1 << 21 : 0) | ((src[srcPos + 22] & 0xFFFF) <= threshold ? 1 << 22 : 0) | ((src[srcPos + 23] & 0xFFFF) <= threshold ? 1 << 23 : 0) | ((src[srcPos + 24] & 0xFFFF) <= threshold ? 1 << 24 : 0) | ((src[srcPos + 25] & 0xFFFF) <= threshold ? 1 << 25 : 0) | ((src[srcPos + 26] & 0xFFFF) <= threshold ? 1 << 26 : 0) | ((src[srcPos + 27] & 0xFFFF) <= threshold ? 1 << 27 : 0) | ((src[srcPos + 28] & 0xFFFF) <= threshold ? 1 << 28 : 0) | ((src[srcPos + 29] & 0xFFFF) <= threshold ? 1 << 29 : 0) | ((src[srcPos + 30] & 0xFFFF) <= threshold ? 1 << 30 : 0) | ((src[srcPos + 31] & 0xFFFF) <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if ((src[srcPos] & 0xFFFF) <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked int values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, int[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked int values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, int[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked int values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, int[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked int values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, int[] src, int srcPos, int count, int threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, long[] src, int srcPos, int count, long threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, long[] src, int srcPos, int count, long threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, long[] src, int srcPos, int count, long threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, long[] src, int srcPos, int count, long threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked float values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, float[] src, int srcPos, int count, float threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked float values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, float[] src, int srcPos, int count, float threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked float values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, float[] src, int srcPos, int count, float threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked float values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, float[] src, int srcPos, int count, float threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] > threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked double values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than this value are packed to unit bits (1), * the source elements less than or equal to this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreater( long[] dest, long destPos, double[] src, int srcPos, int count, double threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] > threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] > threshold ? 1 << 1 : 0) | (src[srcPos + 2] > threshold ? 1 << 2 : 0) | (src[srcPos + 3] > threshold ? 1 << 3 : 0) | (src[srcPos + 4] > threshold ? 1 << 4 : 0) | (src[srcPos + 5] > threshold ? 1 << 5 : 0) | (src[srcPos + 6] > threshold ? 1 << 6 : 0) | (src[srcPos + 7] > threshold ? 1 << 7 : 0) | (src[srcPos + 8] > threshold ? 1 << 8 : 0) | (src[srcPos + 9] > threshold ? 1 << 9 : 0) | (src[srcPos + 10] > threshold ? 1 << 10 : 0) | (src[srcPos + 11] > threshold ? 1 << 11 : 0) | (src[srcPos + 12] > threshold ? 1 << 12 : 0) | (src[srcPos + 13] > threshold ? 1 << 13 : 0) | (src[srcPos + 14] > threshold ? 1 << 14 : 0) | (src[srcPos + 15] > threshold ? 1 << 15 : 0) | (src[srcPos + 16] > threshold ? 1 << 16 : 0) | (src[srcPos + 17] > threshold ? 1 << 17 : 0) | (src[srcPos + 18] > threshold ? 1 << 18 : 0) | (src[srcPos + 19] > threshold ? 1 << 19 : 0) | (src[srcPos + 20] > threshold ? 1 << 20 : 0) | (src[srcPos + 21] > threshold ? 1 << 21 : 0) | (src[srcPos + 22] > threshold ? 1 << 22 : 0) | (src[srcPos + 23] > threshold ? 1 << 23 : 0) | (src[srcPos + 24] > threshold ? 1 << 24 : 0) | (src[srcPos + 25] > threshold ? 1 << 25 : 0) | (src[srcPos + 26] > threshold ? 1 << 26 : 0) | (src[srcPos + 27] > threshold ? 1 << 27 : 0) | (src[srcPos + 28] > threshold ? 1 << 28 : 0) | (src[srcPos + 29] > threshold ? 1 << 29 : 0) | (src[srcPos + 30] > threshold ? 1 << 30 : 0) | (src[srcPos + 31] > threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] > threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] < threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked double values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than to this value are packed to unit bits (1), * the source elements greater than or equal this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLess( long[] dest, long destPos, double[] src, int srcPos, int count, double threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] < threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] < threshold ? 1 << 1 : 0) | (src[srcPos + 2] < threshold ? 1 << 2 : 0) | (src[srcPos + 3] < threshold ? 1 << 3 : 0) | (src[srcPos + 4] < threshold ? 1 << 4 : 0) | (src[srcPos + 5] < threshold ? 1 << 5 : 0) | (src[srcPos + 6] < threshold ? 1 << 6 : 0) | (src[srcPos + 7] < threshold ? 1 << 7 : 0) | (src[srcPos + 8] < threshold ? 1 << 8 : 0) | (src[srcPos + 9] < threshold ? 1 << 9 : 0) | (src[srcPos + 10] < threshold ? 1 << 10 : 0) | (src[srcPos + 11] < threshold ? 1 << 11 : 0) | (src[srcPos + 12] < threshold ? 1 << 12 : 0) | (src[srcPos + 13] < threshold ? 1 << 13 : 0) | (src[srcPos + 14] < threshold ? 1 << 14 : 0) | (src[srcPos + 15] < threshold ? 1 << 15 : 0) | (src[srcPos + 16] < threshold ? 1 << 16 : 0) | (src[srcPos + 17] < threshold ? 1 << 17 : 0) | (src[srcPos + 18] < threshold ? 1 << 18 : 0) | (src[srcPos + 19] < threshold ? 1 << 19 : 0) | (src[srcPos + 20] < threshold ? 1 << 20 : 0) | (src[srcPos + 21] < threshold ? 1 << 21 : 0) | (src[srcPos + 22] < threshold ? 1 << 22 : 0) | (src[srcPos + 23] < threshold ? 1 << 23 : 0) | (src[srcPos + 24] < threshold ? 1 << 24 : 0) | (src[srcPos + 25] < threshold ? 1 << 25 : 0) | (src[srcPos + 26] < threshold ? 1 << 26 : 0) | (src[srcPos + 27] < threshold ? 1 << 27 : 0) | (src[srcPos + 28] < threshold ? 1 << 28 : 0) | (src[srcPos + 29] < threshold ? 1 << 29 : 0) | (src[srcPos + 30] < threshold ? 1 << 30 : 0) | (src[srcPos + 31] < threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] < threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] >= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked double values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are greater than or equal to this value are packed to unit bits (1), * the source elements less than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsGreaterOrEqual( long[] dest, long destPos, double[] src, int srcPos, int count, double threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] >= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] >= threshold ? 1 << 1 : 0) | (src[srcPos + 2] >= threshold ? 1 << 2 : 0) | (src[srcPos + 3] >= threshold ? 1 << 3 : 0) | (src[srcPos + 4] >= threshold ? 1 << 4 : 0) | (src[srcPos + 5] >= threshold ? 1 << 5 : 0) | (src[srcPos + 6] >= threshold ? 1 << 6 : 0) | (src[srcPos + 7] >= threshold ? 1 << 7 : 0) | (src[srcPos + 8] >= threshold ? 1 << 8 : 0) | (src[srcPos + 9] >= threshold ? 1 << 9 : 0) | (src[srcPos + 10] >= threshold ? 1 << 10 : 0) | (src[srcPos + 11] >= threshold ? 1 << 11 : 0) | (src[srcPos + 12] >= threshold ? 1 << 12 : 0) | (src[srcPos + 13] >= threshold ? 1 << 13 : 0) | (src[srcPos + 14] >= threshold ? 1 << 14 : 0) | (src[srcPos + 15] >= threshold ? 1 << 15 : 0) | (src[srcPos + 16] >= threshold ? 1 << 16 : 0) | (src[srcPos + 17] >= threshold ? 1 << 17 : 0) | (src[srcPos + 18] >= threshold ? 1 << 18 : 0) | (src[srcPos + 19] >= threshold ? 1 << 19 : 0) | (src[srcPos + 20] >= threshold ? 1 << 20 : 0) | (src[srcPos + 21] >= threshold ? 1 << 21 : 0) | (src[srcPos + 22] >= threshold ? 1 << 22 : 0) | (src[srcPos + 23] >= threshold ? 1 << 23 : 0) | (src[srcPos + 24] >= threshold ? 1 << 24 : 0) | (src[srcPos + 25] >= threshold ? 1 << 25 : 0) | (src[srcPos + 26] >= threshold ? 1 << 26 : 0) | (src[srcPos + 27] >= threshold ? 1 << 27 : 0) | (src[srcPos + 28] >= threshold ? 1 << 28 : 0) | (src[srcPos + 29] >= threshold ? 1 << 29 : 0) | (src[srcPos + 30] >= threshold ? 1 << 30 : 0) | (src[srcPos + 31] >= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] >= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /** * Packs count elements from src array, starting from the element #srcPos, * to packed dest array, starting from the bit #destPos, * so that every element src[k] is transformed to boolean (bit) value * {@code src[k] <= threshold}. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (unpacked double values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be packed (must be >=0). * @param threshold the source elements that are less than or equal to this value are packed to unit bits (1), * the source elements greater than this threshold are packed to zero bits (0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void packBitsLessOrEqual( long[] dest, long destPos, double[] src, int srcPos, int count, double threshold) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (destPos & 63) == 0 ? 0 : 64 - (int) (destPos & 63); if (countStart > count) countStart = count; if (countStart > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countStart; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } count -= countStart; int cnt = count >>> 6; for (int k = (int) (destPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; int high = (src[srcPos] <= threshold ? 1 : 0) // - "0x80000000" below to avoid IDE warning about possible overflow | (src[srcPos + 1] <= threshold ? 1 << 1 : 0) | (src[srcPos + 2] <= threshold ? 1 << 2 : 0) | (src[srcPos + 3] <= threshold ? 1 << 3 : 0) | (src[srcPos + 4] <= threshold ? 1 << 4 : 0) | (src[srcPos + 5] <= threshold ? 1 << 5 : 0) | (src[srcPos + 6] <= threshold ? 1 << 6 : 0) | (src[srcPos + 7] <= threshold ? 1 << 7 : 0) | (src[srcPos + 8] <= threshold ? 1 << 8 : 0) | (src[srcPos + 9] <= threshold ? 1 << 9 : 0) | (src[srcPos + 10] <= threshold ? 1 << 10 : 0) | (src[srcPos + 11] <= threshold ? 1 << 11 : 0) | (src[srcPos + 12] <= threshold ? 1 << 12 : 0) | (src[srcPos + 13] <= threshold ? 1 << 13 : 0) | (src[srcPos + 14] <= threshold ? 1 << 14 : 0) | (src[srcPos + 15] <= threshold ? 1 << 15 : 0) | (src[srcPos + 16] <= threshold ? 1 << 16 : 0) | (src[srcPos + 17] <= threshold ? 1 << 17 : 0) | (src[srcPos + 18] <= threshold ? 1 << 18 : 0) | (src[srcPos + 19] <= threshold ? 1 << 19 : 0) | (src[srcPos + 20] <= threshold ? 1 << 20 : 0) | (src[srcPos + 21] <= threshold ? 1 << 21 : 0) | (src[srcPos + 22] <= threshold ? 1 << 22 : 0) | (src[srcPos + 23] <= threshold ? 1 << 23 : 0) | (src[srcPos + 24] <= threshold ? 1 << 24 : 0) | (src[srcPos + 25] <= threshold ? 1 << 25 : 0) | (src[srcPos + 26] <= threshold ? 1 << 26 : 0) | (src[srcPos + 27] <= threshold ? 1 << 27 : 0) | (src[srcPos + 28] <= threshold ? 1 << 28 : 0) | (src[srcPos + 29] <= threshold ? 1 << 29 : 0) | (src[srcPos + 30] <= threshold ? 1 << 30 : 0) | (src[srcPos + 31] <= threshold ? 0x80000000 : 0) // - end of autogenerated 30 lines ; srcPos += 32; dest[k] = ((long) low & 0xFFFFFFFFL) | (((long) high) << 32); destPos += 64; } int countFinish = count & 63; if (countFinish > 0) { synchronized (dest) { for (int srcPosMax = srcPos + countFinish; srcPos < srcPosMax; srcPos++, destPos++) { if (src[srcPos] <= threshold) dest[(int) (destPos >>> 6)] |= 1L << (destPos & 63); else dest[(int) (destPos >>> 6)] &= ~(1L << (destPos & 63)); } } } } /*Repeat.AutoGeneratedEnd*/ /*Repeat.SectionStart unpackBits*/ /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array boolean[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k). * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(boolean[], int, long[], long, int)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @return the unpacked boolean array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static boolean[] unpackBits(long[] src, long srcPos, long count) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final boolean[] result = new boolean[(int) count]; unpackBits(result, 0, src, srcPos, result.length); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest boolean array, starting from the element #destPos. * * @param dest the destination array (unpacked boolean values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be unpacked (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits(boolean[] dest, int destPos, long[] src, long srcPos, int count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() dest\[.*?0; ==> // dest[destPos + $INDEX(start=1)] = (low & (1 << $INDEX(start=1))) != 0; ,, ...(31);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] dest[destPos] = (low & 1) != 0; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 1] = (low & (1 << 1)) != 0; dest[destPos + 2] = (low & (1 << 2)) != 0; dest[destPos + 3] = (low & (1 << 3)) != 0; dest[destPos + 4] = (low & (1 << 4)) != 0; dest[destPos + 5] = (low & (1 << 5)) != 0; dest[destPos + 6] = (low & (1 << 6)) != 0; dest[destPos + 7] = (low & (1 << 7)) != 0; dest[destPos + 8] = (low & (1 << 8)) != 0; dest[destPos + 9] = (low & (1 << 9)) != 0; dest[destPos + 10] = (low & (1 << 10)) != 0; dest[destPos + 11] = (low & (1 << 11)) != 0; dest[destPos + 12] = (low & (1 << 12)) != 0; dest[destPos + 13] = (low & (1 << 13)) != 0; dest[destPos + 14] = (low & (1 << 14)) != 0; dest[destPos + 15] = (low & (1 << 15)) != 0; dest[destPos + 16] = (low & (1 << 16)) != 0; dest[destPos + 17] = (low & (1 << 17)) != 0; dest[destPos + 18] = (low & (1 << 18)) != 0; dest[destPos + 19] = (low & (1 << 19)) != 0; dest[destPos + 20] = (low & (1 << 20)) != 0; dest[destPos + 21] = (low & (1 << 21)) != 0; dest[destPos + 22] = (low & (1 << 22)) != 0; dest[destPos + 23] = (low & (1 << 23)) != 0; dest[destPos + 24] = (low & (1 << 24)) != 0; dest[destPos + 25] = (low & (1 << 25)) != 0; dest[destPos + 26] = (low & (1 << 26)) != 0; dest[destPos + 27] = (low & (1 << 27)) != 0; dest[destPos + 28] = (low & (1 << 28)) != 0; dest[destPos + 29] = (low & (1 << 29)) != 0; dest[destPos + 30] = (low & (1 << 30)) != 0; dest[destPos + 31] = (low & (0x80000000)) != 0; //[[Repeat.AutoGeneratedEnd]] // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() dest\[.*?0; ==> // dest[destPos + $INDEX(start=33)] = (high & (1 << $INDEX(start=1))) != 0; ,, ...(31);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] dest[destPos + 32] = (high & 0x1) != 0; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 33] = (high & (1 << 1)) != 0; dest[destPos + 34] = (high & (1 << 2)) != 0; dest[destPos + 35] = (high & (1 << 3)) != 0; dest[destPos + 36] = (high & (1 << 4)) != 0; dest[destPos + 37] = (high & (1 << 5)) != 0; dest[destPos + 38] = (high & (1 << 6)) != 0; dest[destPos + 39] = (high & (1 << 7)) != 0; dest[destPos + 40] = (high & (1 << 8)) != 0; dest[destPos + 41] = (high & (1 << 9)) != 0; dest[destPos + 42] = (high & (1 << 10)) != 0; dest[destPos + 43] = (high & (1 << 11)) != 0; dest[destPos + 44] = (high & (1 << 12)) != 0; dest[destPos + 45] = (high & (1 << 13)) != 0; dest[destPos + 46] = (high & (1 << 14)) != 0; dest[destPos + 47] = (high & (1 << 15)) != 0; dest[destPos + 48] = (high & (1 << 16)) != 0; dest[destPos + 49] = (high & (1 << 17)) != 0; dest[destPos + 50] = (high & (1 << 18)) != 0; dest[destPos + 51] = (high & (1 << 19)) != 0; dest[destPos + 52] = (high & (1 << 20)) != 0; dest[destPos + 53] = (high & (1 << 21)) != 0; dest[destPos + 54] = (high & (1 << 22)) != 0; dest[destPos + 55] = (high & (1 << 23)) != 0; dest[destPos + 56] = (high & (1 << 24)) != 0; dest[destPos + 57] = (high & (1 << 25)) != 0; dest[destPos + 58] = (high & (1 << 26)) != 0; dest[destPos + 59] = (high & (1 << 27)) != 0; dest[destPos + 60] = (high & (1 << 28)) != 0; dest[destPos + 61] = (high & (1 << 29)) != 0; dest[destPos + 62] = (high & (1 << 30)) != 0; dest[destPos + 63] = (high & (0x80000000)) != 0; //[[Repeat.AutoGeneratedEnd]] destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L; } } /*Repeat.SectionEnd unpackBits*/ /*Repeat() (\/\*\*.*?\*\/\s+ public static boolean\[\] unpackBits)(\(.*?return result;\s*\}\s*) ==> $1ToChars$2,,$1ToBytes$2,,$1ToShorts$2,,$1ToInts$2,,$1ToLongs$2,,$1ToFloats$2,,$1ToDoubles$2,, ;; boolean ==> char,,byte,,short,,int,,long,,float,,double,,T;; Booleans ==> Chars,,Bytes,,Shorts,,Ints,,Longs,,Floats,,Doubles,,Objects;; (void unpack(?:Unit|Zero)?Bits\(\s*T\[\]) ==> $1,,... */ /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array boolean[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(boolean[], int, long[], long, int, boolean, boolean)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked boolean array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static boolean[] unpackBits( long[] src, long srcPos, long count, boolean bit0Value, boolean bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final boolean[] result = new boolean[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest boolean array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked boolean values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( boolean[] dest, int destPos, long[] src, long srcPos, int count, boolean bit0Value, boolean bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() dest\[.*?0\s*\? ==> // dest[destPos + $INDEX(start=1)] = (low & (1 << $INDEX(start=1))) != 0 ?,, ...(31);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; //[[Repeat.AutoGeneratedEnd]] // - "0x80000000" below to avoid IDE warning about possible overflow //[[Repeat() dest\[.*?0\s+\? ==> // dest[destPos + $INDEX(start=33)] = (high & (1 << $INDEX(start=1))) != 0 ?,, ...(31);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; //[[Repeat.AutoGeneratedEnd]] destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest boolean array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked boolean values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( boolean[] dest, int destPos, long[] src, long srcPos, int count, boolean bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { //[[Repeat() if.*?\] ==> // if ((low & (1 << $INDEX(start=1))) != 0) dest[destPos + $INDEX(start=1)],, ...(15)]] if ((low & 1) != 0) dest[destPos] = bit1Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; //[[Repeat.AutoGeneratedEnd]] } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { //[[Repeat() if.*?\] ==> // if ((low & (1 << $INDEX(start=17))) != 0) dest[destPos + $INDEX(start=17)],, ...(15);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; //[[Repeat.AutoGeneratedEnd]] } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { //[[Repeat() if.*?\] ==> // if ((high & (1 << $INDEX(start=1))) != 0) dest[destPos + $INDEX(start=33)],, ...(15)]] if ((high & 1) != 0) dest[destPos + 32] = bit1Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; //[[Repeat.AutoGeneratedEnd]] } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { //[[Repeat() if.*?\] ==> // if ((high & (1 << $INDEX(start=17))) != 0) dest[destPos + $INDEX(start=49)],, ...(15);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; //[[Repeat.AutoGeneratedEnd]] } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest boolean array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked boolean values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( boolean[] dest, int destPos, long[] src, long srcPos, int count, boolean bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { //[[Repeat() if.*?\] ==> // if ((low & (1 << $INDEX(start=1))) == 0) dest[destPos + $INDEX(start=1)],, ...(15)]] if ((low & 1) == 0) dest[destPos] = bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; //[[Repeat.AutoGeneratedEnd]] } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { //[[Repeat() if.*?\] ==> // if ((low & (1 << $INDEX(start=17))) == 0) dest[destPos + $INDEX(start=17)],, ...(15);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; //[[Repeat.AutoGeneratedEnd]] } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { //[[Repeat() if.*?\] ==> // if ((high & (1 << $INDEX(start=1))) == 0) dest[destPos + $INDEX(start=33)],, ...(15)]] if ((high & 1) == 0) dest[destPos + 32] = bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; //[[Repeat.AutoGeneratedEnd]] } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { //[[Repeat() if.*?\] ==> // if ((high & (1 << $INDEX(start=17))) == 0) dest[destPos + $INDEX(start=49)],, ...(15);; // 1\s<<\s+31 ==> 0x80000000,, ... ]] if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; //[[Repeat.AutoGeneratedEnd]] } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */ /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array char[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(char[], int, long[], long, int, char, char)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked char array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static char[] unpackBitsToChars( long[] src, long srcPos, long count, char bit0Value, char bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final char[] result = new char[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest char array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked char values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( char[] dest, int destPos, long[] src, long srcPos, int count, char bit0Value, char bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest char array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked char values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( char[] dest, int destPos, long[] src, long srcPos, int count, char bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest char array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked char values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( char[] dest, int destPos, long[] src, long srcPos, int count, char bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array byte[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(byte[], int, long[], long, int, byte, byte)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked byte array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static byte[] unpackBitsToBytes( long[] src, long srcPos, long count, byte bit0Value, byte bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final byte[] result = new byte[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest byte array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked byte values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( byte[] dest, int destPos, long[] src, long srcPos, int count, byte bit0Value, byte bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest byte array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked byte values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( byte[] dest, int destPos, long[] src, long srcPos, int count, byte bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest byte array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked byte values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( byte[] dest, int destPos, long[] src, long srcPos, int count, byte bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array short[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(short[], int, long[], long, int, short, short)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked short array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static short[] unpackBitsToShorts( long[] src, long srcPos, long count, short bit0Value, short bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final short[] result = new short[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest short array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked short values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( short[] dest, int destPos, long[] src, long srcPos, int count, short bit0Value, short bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest short array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked short values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( short[] dest, int destPos, long[] src, long srcPos, int count, short bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest short array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked short values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( short[] dest, int destPos, long[] src, long srcPos, int count, short bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array int[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(int[], int, long[], long, int, int, int)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked int array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static int[] unpackBitsToInts( long[] src, long srcPos, long count, int bit0Value, int bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final int[] result = new int[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest int array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked int values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( int[] dest, int destPos, long[] src, long srcPos, int count, int bit0Value, int bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest int array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked int values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( int[] dest, int destPos, long[] src, long srcPos, int count, int bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest int array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked int values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( int[] dest, int destPos, long[] src, long srcPos, int count, int bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array long[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(long[], int, long[], long, int, long, long)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked long array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static long[] unpackBitsToLongs( long[] src, long srcPos, long count, long bit0Value, long bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final long[] result = new long[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest long array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked long values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( long[] dest, int destPos, long[] src, long srcPos, int count, long bit0Value, long bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest long array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked long values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( long[] dest, int destPos, long[] src, long srcPos, int count, long bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest long array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked long values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( long[] dest, int destPos, long[] src, long srcPos, int count, long bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array float[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(float[], int, long[], long, int, float, float)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked float array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static float[] unpackBitsToFloats( long[] src, long srcPos, long count, float bit0Value, float bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final float[] result = new float[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest float array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked float values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( float[] dest, int destPos, long[] src, long srcPos, int count, float bit0Value, float bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest float array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked float values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( float[] dest, int destPos, long[] src, long srcPos, int count, float bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest float array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked float values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( float[] dest, int destPos, long[] src, long srcPos, int count, float bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * into a newly created array double[count] array returned as a result. * Every element result[k] of the result array is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * *

Note that this method provides more user-friendly exception messages in a case * of incorrect arguments, than {@link #unpackBits(double[], int, long[], long, int, double, double)} * method.

* *

Note: count argument is declared as long, * but actually it must be in 0..Integer.MAX_VALUE range; in another case, * this method throws an exception. Using long * type instead of int may make this method more convenient to use in some situations.

* * @param src the source array (bits are packed in byte values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked * (must be in 0..Integer.MAX_VALUE range). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @return the unpacked double array. * @throws NullPointerException ifsrc is {@code null}. * @throws IllegalArgumentException if srcPos or count is negative, or * if copying would cause access of data outside the source array bounds. * @throws TooLargeArrayException if count > Integer.MAX_VALUE (cannot create the result array). */ public static double[] unpackBitsToDoubles( long[] src, long srcPos, long count, double bit0Value, double bit1Value) { Objects.requireNonNull(src, "Null src"); if (srcPos < 0) { throw new IllegalArgumentException("Negative srcPos = " + srcPos); } if (count < 0) { throw new IllegalArgumentException("Negative count = " + count); } if (count > unpackedLength(src) - srcPos) { throw new IllegalArgumentException("Too short source array byte[" + src.length + "]: it cannot contain " + count + " bits since position " + srcPos); } if (count > Integer.MAX_VALUE) { throw new TooLargeArrayException("Too large bit array for unpacking to Java array: " + count + " >= 2^31 bits"); } final double[] result = new double[(int) count]; unpackBits(result, 0, src, srcPos, result.length, bit0Value, bit1Value); return result; } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest double array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked double values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( double[] dest, int destPos, long[] src, long srcPos, int count, double bit0Value, double bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest double array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked double values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( double[] dest, int destPos, long[] src, long srcPos, int count, double bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest double array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked double values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( double[] dest, int destPos, long[] src, long srcPos, int count, double bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * to dest T array, starting from the element #destPos. * It means that every element dest[destPos+k] is assigned to * {@link #getBit getBit}(srcPos+k)?bit1Value:bit0Value. * * @param dest the destination array (unpacked T values). * @param destPos position of the first written element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements in the destination array to which the bit 0 is translated. * @param bit1Value the value of elements in the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackBits( T[] dest, int destPos, long[] src, long srcPos, int count, T bit0Value, T bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (bit0Value == bit1Value) { java.util.Arrays.fill(dest, destPos, destPos + count, bit0Value); return; } int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos] = (low & 1) != 0 ? bit1Value : bit0Value; dest[destPos + 1] = (low & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 2] = (low & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 3] = (low & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 4] = (low & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 5] = (low & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 6] = (low & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 7] = (low & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 8] = (low & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 9] = (low & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 10] = (low & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 11] = (low & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 12] = (low & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 13] = (low & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 14] = (low & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 15] = (low & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 16] = (low & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 17] = (low & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 18] = (low & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 19] = (low & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 20] = (low & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 21] = (low & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 22] = (low & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 23] = (low & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 24] = (low & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 25] = (low & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 26] = (low & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 27] = (low & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 28] = (low & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 29] = (low & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 30] = (low & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 31] = (low & (0x80000000)) != 0 ? bit1Value : bit0Value; // - "0x80000000" below to avoid IDE warning about possible overflow dest[destPos + 32] = (high & 0x1) != 0 ? bit1Value : bit0Value; dest[destPos + 33] = (high & (1 << 1)) != 0 ? bit1Value : bit0Value; dest[destPos + 34] = (high & (1 << 2)) != 0 ? bit1Value : bit0Value; dest[destPos + 35] = (high & (1 << 3)) != 0 ? bit1Value : bit0Value; dest[destPos + 36] = (high & (1 << 4)) != 0 ? bit1Value : bit0Value; dest[destPos + 37] = (high & (1 << 5)) != 0 ? bit1Value : bit0Value; dest[destPos + 38] = (high & (1 << 6)) != 0 ? bit1Value : bit0Value; dest[destPos + 39] = (high & (1 << 7)) != 0 ? bit1Value : bit0Value; dest[destPos + 40] = (high & (1 << 8)) != 0 ? bit1Value : bit0Value; dest[destPos + 41] = (high & (1 << 9)) != 0 ? bit1Value : bit0Value; dest[destPos + 42] = (high & (1 << 10)) != 0 ? bit1Value : bit0Value; dest[destPos + 43] = (high & (1 << 11)) != 0 ? bit1Value : bit0Value; dest[destPos + 44] = (high & (1 << 12)) != 0 ? bit1Value : bit0Value; dest[destPos + 45] = (high & (1 << 13)) != 0 ? bit1Value : bit0Value; dest[destPos + 46] = (high & (1 << 14)) != 0 ? bit1Value : bit0Value; dest[destPos + 47] = (high & (1 << 15)) != 0 ? bit1Value : bit0Value; dest[destPos + 48] = (high & (1 << 16)) != 0 ? bit1Value : bit0Value; dest[destPos + 49] = (high & (1 << 17)) != 0 ? bit1Value : bit0Value; dest[destPos + 50] = (high & (1 << 18)) != 0 ? bit1Value : bit0Value; dest[destPos + 51] = (high & (1 << 19)) != 0 ? bit1Value : bit0Value; dest[destPos + 52] = (high & (1 << 20)) != 0 ? bit1Value : bit0Value; dest[destPos + 53] = (high & (1 << 21)) != 0 ? bit1Value : bit0Value; dest[destPos + 54] = (high & (1 << 22)) != 0 ? bit1Value : bit0Value; dest[destPos + 55] = (high & (1 << 23)) != 0 ? bit1Value : bit0Value; dest[destPos + 56] = (high & (1 << 24)) != 0 ? bit1Value : bit0Value; dest[destPos + 57] = (high & (1 << 25)) != 0 ? bit1Value : bit0Value; dest[destPos + 58] = (high & (1 << 26)) != 0 ? bit1Value : bit0Value; dest[destPos + 59] = (high & (1 << 27)) != 0 ? bit1Value : bit0Value; dest[destPos + 60] = (high & (1 << 28)) != 0 ? bit1Value : bit0Value; dest[destPos + 61] = (high & (1 << 29)) != 0 ? bit1Value : bit0Value; dest[destPos + 62] = (high & (1 << 30)) != 0 ? bit1Value : bit0Value; dest[destPos + 63] = (high & (0x80000000)) != 0 ? bit1Value : bit0Value; destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] = (src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L ? bit1Value : bit0Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 1 sets the corresponding element of dest T array, * starting from the element #destPos, to bit1Value. * Elements of dest array, corresponding to zero bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?bit1Value:dest[destPos+k]. * * @param dest the destination array (unpacked T values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit1Value the value of elements of the destination array to which the bit 1 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackUnitBits( T[] dest, int destPos, long[] src, long srcPos, int count, T bit1Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF) != 0) { if ((low & 1) != 0) dest[destPos] = bit1Value; if ((low & (1 << 1)) != 0) dest[destPos + 1] = bit1Value; if ((low & (1 << 2)) != 0) dest[destPos + 2] = bit1Value; if ((low & (1 << 3)) != 0) dest[destPos + 3] = bit1Value; if ((low & (1 << 4)) != 0) dest[destPos + 4] = bit1Value; if ((low & (1 << 5)) != 0) dest[destPos + 5] = bit1Value; if ((low & (1 << 6)) != 0) dest[destPos + 6] = bit1Value; if ((low & (1 << 7)) != 0) dest[destPos + 7] = bit1Value; if ((low & (1 << 8)) != 0) dest[destPos + 8] = bit1Value; if ((low & (1 << 9)) != 0) dest[destPos + 9] = bit1Value; if ((low & (1 << 10)) != 0) dest[destPos + 10] = bit1Value; if ((low & (1 << 11)) != 0) dest[destPos + 11] = bit1Value; if ((low & (1 << 12)) != 0) dest[destPos + 12] = bit1Value; if ((low & (1 << 13)) != 0) dest[destPos + 13] = bit1Value; if ((low & (1 << 14)) != 0) dest[destPos + 14] = bit1Value; if ((low & (1 << 15)) != 0) dest[destPos + 15] = bit1Value; } if ((low & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((low & 0xFFFF0000) != 0) { if ((low & (1 << 16)) != 0) dest[destPos + 16] = bit1Value; if ((low & (1 << 17)) != 0) dest[destPos + 17] = bit1Value; if ((low & (1 << 18)) != 0) dest[destPos + 18] = bit1Value; if ((low & (1 << 19)) != 0) dest[destPos + 19] = bit1Value; if ((low & (1 << 20)) != 0) dest[destPos + 20] = bit1Value; if ((low & (1 << 21)) != 0) dest[destPos + 21] = bit1Value; if ((low & (1 << 22)) != 0) dest[destPos + 22] = bit1Value; if ((low & (1 << 23)) != 0) dest[destPos + 23] = bit1Value; if ((low & (1 << 24)) != 0) dest[destPos + 24] = bit1Value; if ((low & (1 << 25)) != 0) dest[destPos + 25] = bit1Value; if ((low & (1 << 26)) != 0) dest[destPos + 26] = bit1Value; if ((low & (1 << 27)) != 0) dest[destPos + 27] = bit1Value; if ((low & (1 << 28)) != 0) dest[destPos + 28] = bit1Value; if ((low & (1 << 29)) != 0) dest[destPos + 29] = bit1Value; if ((low & (1 << 30)) != 0) dest[destPos + 30] = bit1Value; if ((low & (0x80000000)) != 0) dest[destPos + 31] = bit1Value; } if ((high & 0xFFFF) == 0xFFFF) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF) != 0) { if ((high & 1) != 0) dest[destPos + 32] = bit1Value; if ((high & (1 << 1)) != 0) dest[destPos + 33] = bit1Value; if ((high & (1 << 2)) != 0) dest[destPos + 34] = bit1Value; if ((high & (1 << 3)) != 0) dest[destPos + 35] = bit1Value; if ((high & (1 << 4)) != 0) dest[destPos + 36] = bit1Value; if ((high & (1 << 5)) != 0) dest[destPos + 37] = bit1Value; if ((high & (1 << 6)) != 0) dest[destPos + 38] = bit1Value; if ((high & (1 << 7)) != 0) dest[destPos + 39] = bit1Value; if ((high & (1 << 8)) != 0) dest[destPos + 40] = bit1Value; if ((high & (1 << 9)) != 0) dest[destPos + 41] = bit1Value; if ((high & (1 << 10)) != 0) dest[destPos + 42] = bit1Value; if ((high & (1 << 11)) != 0) dest[destPos + 43] = bit1Value; if ((high & (1 << 12)) != 0) dest[destPos + 44] = bit1Value; if ((high & (1 << 13)) != 0) dest[destPos + 45] = bit1Value; if ((high & (1 << 14)) != 0) dest[destPos + 46] = bit1Value; if ((high & (1 << 15)) != 0) dest[destPos + 47] = bit1Value; } if ((high & 0xFFFF0000) == 0xFFFF0000) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit1Value; } } else if ((high & 0xFFFF0000) != 0) { if ((high & (1 << 16)) != 0) dest[destPos + 48] = bit1Value; if ((high & (1 << 17)) != 0) dest[destPos + 49] = bit1Value; if ((high & (1 << 18)) != 0) dest[destPos + 50] = bit1Value; if ((high & (1 << 19)) != 0) dest[destPos + 51] = bit1Value; if ((high & (1 << 20)) != 0) dest[destPos + 52] = bit1Value; if ((high & (1 << 21)) != 0) dest[destPos + 53] = bit1Value; if ((high & (1 << 22)) != 0) dest[destPos + 54] = bit1Value; if ((high & (1 << 23)) != 0) dest[destPos + 55] = bit1Value; if ((high & (1 << 24)) != 0) dest[destPos + 56] = bit1Value; if ((high & (1 << 25)) != 0) dest[destPos + 57] = bit1Value; if ((high & (1 << 26)) != 0) dest[destPos + 58] = bit1Value; if ((high & (1 << 27)) != 0) dest[destPos + 59] = bit1Value; if ((high & (1 << 28)) != 0) dest[destPos + 60] = bit1Value; if ((high & (1 << 29)) != 0) dest[destPos + 61] = bit1Value; if ((high & (1 << 30)) != 0) dest[destPos + 62] = bit1Value; if ((high & (0x80000000)) != 0) dest[destPos + 63] = bit1Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) != 0L) dest[destPos] = bit1Value; } } /** * Tests count bits, packed in src array, starting from the bit #srcPos, * and for every found bit 0 sets the corresponding element of dest T array, * starting from the element #destPos, to bit0Value. * Elements of dest array, corresponding to unit bits of the source array, are not changed. * In other words, every element dest[destPos+k] is assigned to new value * {@link #getBit getBit}(srcPos+k)?dest[destPos+k]:bit0Value. * * @param dest the destination array (unpacked T values). * @param destPos position of the first element in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of elements to be unpacked (must be >=0). * @param bit0Value the value of elements of the destination array to which the bit 0 is translated. * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void unpackZeroBits( T[] dest, int destPos, long[] src, long srcPos, int count, T bit0Value) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } count -= countStart; int cnt = count >>> 6; int fillPos = -1; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; if ((low & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos, 16); fillPos = destPos; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF) != 0xFFFF) { if ((low & 1) == 0) dest[destPos] = bit0Value; if ((low & (1 << 1)) == 0) dest[destPos + 1] = bit0Value; if ((low & (1 << 2)) == 0) dest[destPos + 2] = bit0Value; if ((low & (1 << 3)) == 0) dest[destPos + 3] = bit0Value; if ((low & (1 << 4)) == 0) dest[destPos + 4] = bit0Value; if ((low & (1 << 5)) == 0) dest[destPos + 5] = bit0Value; if ((low & (1 << 6)) == 0) dest[destPos + 6] = bit0Value; if ((low & (1 << 7)) == 0) dest[destPos + 7] = bit0Value; if ((low & (1 << 8)) == 0) dest[destPos + 8] = bit0Value; if ((low & (1 << 9)) == 0) dest[destPos + 9] = bit0Value; if ((low & (1 << 10)) == 0) dest[destPos + 10] = bit0Value; if ((low & (1 << 11)) == 0) dest[destPos + 11] = bit0Value; if ((low & (1 << 12)) == 0) dest[destPos + 12] = bit0Value; if ((low & (1 << 13)) == 0) dest[destPos + 13] = bit0Value; if ((low & (1 << 14)) == 0) dest[destPos + 14] = bit0Value; if ((low & (1 << 15)) == 0) dest[destPos + 15] = bit0Value; } if ((low & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 16, 16); fillPos = destPos + 16; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 16; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((low & 0xFFFF0000) != 0xFFFF0000) { if ((low & (1 << 16)) == 0) dest[destPos + 16] = bit0Value; if ((low & (1 << 17)) == 0) dest[destPos + 17] = bit0Value; if ((low & (1 << 18)) == 0) dest[destPos + 18] = bit0Value; if ((low & (1 << 19)) == 0) dest[destPos + 19] = bit0Value; if ((low & (1 << 20)) == 0) dest[destPos + 20] = bit0Value; if ((low & (1 << 21)) == 0) dest[destPos + 21] = bit0Value; if ((low & (1 << 22)) == 0) dest[destPos + 22] = bit0Value; if ((low & (1 << 23)) == 0) dest[destPos + 23] = bit0Value; if ((low & (1 << 24)) == 0) dest[destPos + 24] = bit0Value; if ((low & (1 << 25)) == 0) dest[destPos + 25] = bit0Value; if ((low & (1 << 26)) == 0) dest[destPos + 26] = bit0Value; if ((low & (1 << 27)) == 0) dest[destPos + 27] = bit0Value; if ((low & (1 << 28)) == 0) dest[destPos + 28] = bit0Value; if ((low & (1 << 29)) == 0) dest[destPos + 29] = bit0Value; if ((low & (1 << 30)) == 0) dest[destPos + 30] = bit0Value; if ((low & (0x80000000)) == 0) dest[destPos + 31] = bit0Value; } if ((high & 0xFFFF) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 32, 16); fillPos = destPos + 32; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 32; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF) != 0xFFFF) { if ((high & 1) == 0) dest[destPos + 32] = bit0Value; if ((high & (1 << 1)) == 0) dest[destPos + 33] = bit0Value; if ((high & (1 << 2)) == 0) dest[destPos + 34] = bit0Value; if ((high & (1 << 3)) == 0) dest[destPos + 35] = bit0Value; if ((high & (1 << 4)) == 0) dest[destPos + 36] = bit0Value; if ((high & (1 << 5)) == 0) dest[destPos + 37] = bit0Value; if ((high & (1 << 6)) == 0) dest[destPos + 38] = bit0Value; if ((high & (1 << 7)) == 0) dest[destPos + 39] = bit0Value; if ((high & (1 << 8)) == 0) dest[destPos + 40] = bit0Value; if ((high & (1 << 9)) == 0) dest[destPos + 41] = bit0Value; if ((high & (1 << 10)) == 0) dest[destPos + 42] = bit0Value; if ((high & (1 << 11)) == 0) dest[destPos + 43] = bit0Value; if ((high & (1 << 12)) == 0) dest[destPos + 44] = bit0Value; if ((high & (1 << 13)) == 0) dest[destPos + 45] = bit0Value; if ((high & (1 << 14)) == 0) dest[destPos + 46] = bit0Value; if ((high & (1 << 15)) == 0) dest[destPos + 47] = bit0Value; } if ((high & 0xFFFF0000) == 0) { if (fillPos >= 0) { System.arraycopy(dest, fillPos, dest, destPos + 48, 16); fillPos = destPos + 48; // we prefer copying from minimal distance, due to memory cache } else { fillPos = destPos + 48; for (int i = fillPos, iMax = i + 16; i < iMax; i++) dest[i] = bit0Value; } } else if ((high & 0xFFFF0000) != 0xFFFF0000) { if ((high & (1 << 16)) == 0) dest[destPos + 48] = bit0Value; if ((high & (1 << 17)) == 0) dest[destPos + 49] = bit0Value; if ((high & (1 << 18)) == 0) dest[destPos + 50] = bit0Value; if ((high & (1 << 19)) == 0) dest[destPos + 51] = bit0Value; if ((high & (1 << 20)) == 0) dest[destPos + 52] = bit0Value; if ((high & (1 << 21)) == 0) dest[destPos + 53] = bit0Value; if ((high & (1 << 22)) == 0) dest[destPos + 54] = bit0Value; if ((high & (1 << 23)) == 0) dest[destPos + 55] = bit0Value; if ((high & (1 << 24)) == 0) dest[destPos + 56] = bit0Value; if ((high & (1 << 25)) == 0) dest[destPos + 57] = bit0Value; if ((high & (1 << 26)) == 0) dest[destPos + 58] = bit0Value; if ((high & (1 << 27)) == 0) dest[destPos + 59] = bit0Value; if ((high & (1 << 28)) == 0) dest[destPos + 60] = bit0Value; if ((high & (1 << 29)) == 0) dest[destPos + 61] = bit0Value; if ((high & (1 << 30)) == 0) dest[destPos + 62] = bit0Value; if ((high & (0x80000000)) == 0) dest[destPos + 63] = bit0Value; } destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { if ((src[(int) (srcPos >>> 6)] & (1L << (srcPos & 63))) == 0L) dest[destPos] = bit0Value; } } /*Repeat.AutoGeneratedEnd*/ /** * Unpacks count bits, packed in src array, starting from the bit #srcPos, * and add them count elements of dest array, starting from the element * #destPos. * It means that every element dest[destPos+k] is assigned to * dest[destPos+k]+({@link #getBit getBit}(srcPos+k)?1:0). * * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param dest the destination array (unpacked int values). * @param destPos position of the first increased element in the destination array. * @param count the number of bits to be added to dest elements (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds. */ public static void addBitsToInts(int[] dest, int destPos, long[] src, long srcPos, int count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int countStart = (srcPos & 63) == 0 ? 0 : 64 - (int) (srcPos & 63); if (countStart > count) countStart = count; for (int destPosMax = destPos + countStart; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] += (int) ((src[(int) (srcPos >>> 6)] >>> (srcPos & 63)) & 1); } count -= countStart; int cnt = count >>> 6; for (int k = (int) (srcPos >>> 6), kMax = k + cnt; k < kMax; k++) { int low = (int) src[k]; int high = (int) (src[k] >>> 32); srcPos += 64; //[[Repeat() dest\[.*?1; ==> // dest[destPos + $INDEX(start=1)] += (low >>> $INDEX(start=1)) & 1; ,, ...(31)]] dest[destPos] += low & 1; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 1] += (low >>> 1) & 1; dest[destPos + 2] += (low >>> 2) & 1; dest[destPos + 3] += (low >>> 3) & 1; dest[destPos + 4] += (low >>> 4) & 1; dest[destPos + 5] += (low >>> 5) & 1; dest[destPos + 6] += (low >>> 6) & 1; dest[destPos + 7] += (low >>> 7) & 1; dest[destPos + 8] += (low >>> 8) & 1; dest[destPos + 9] += (low >>> 9) & 1; dest[destPos + 10] += (low >>> 10) & 1; dest[destPos + 11] += (low >>> 11) & 1; dest[destPos + 12] += (low >>> 12) & 1; dest[destPos + 13] += (low >>> 13) & 1; dest[destPos + 14] += (low >>> 14) & 1; dest[destPos + 15] += (low >>> 15) & 1; dest[destPos + 16] += (low >>> 16) & 1; dest[destPos + 17] += (low >>> 17) & 1; dest[destPos + 18] += (low >>> 18) & 1; dest[destPos + 19] += (low >>> 19) & 1; dest[destPos + 20] += (low >>> 20) & 1; dest[destPos + 21] += (low >>> 21) & 1; dest[destPos + 22] += (low >>> 22) & 1; dest[destPos + 23] += (low >>> 23) & 1; dest[destPos + 24] += (low >>> 24) & 1; dest[destPos + 25] += (low >>> 25) & 1; dest[destPos + 26] += (low >>> 26) & 1; dest[destPos + 27] += (low >>> 27) & 1; dest[destPos + 28] += (low >>> 28) & 1; dest[destPos + 29] += (low >>> 29) & 1; dest[destPos + 30] += (low >>> 30) & 1; dest[destPos + 31] += (low >>> 31) & 1; //[[Repeat.AutoGeneratedEnd]] //[[Repeat() dest\[.*?1; ==> // dest[destPos + $INDEX(start=33)] += (high >>> $INDEX(start=1)) & 1; ,, ...(31)]] dest[destPos + 32] += high & 1; //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] dest[destPos + 33] += (high >>> 1) & 1; dest[destPos + 34] += (high >>> 2) & 1; dest[destPos + 35] += (high >>> 3) & 1; dest[destPos + 36] += (high >>> 4) & 1; dest[destPos + 37] += (high >>> 5) & 1; dest[destPos + 38] += (high >>> 6) & 1; dest[destPos + 39] += (high >>> 7) & 1; dest[destPos + 40] += (high >>> 8) & 1; dest[destPos + 41] += (high >>> 9) & 1; dest[destPos + 42] += (high >>> 10) & 1; dest[destPos + 43] += (high >>> 11) & 1; dest[destPos + 44] += (high >>> 12) & 1; dest[destPos + 45] += (high >>> 13) & 1; dest[destPos + 46] += (high >>> 14) & 1; dest[destPos + 47] += (high >>> 15) & 1; dest[destPos + 48] += (high >>> 16) & 1; dest[destPos + 49] += (high >>> 17) & 1; dest[destPos + 50] += (high >>> 18) & 1; dest[destPos + 51] += (high >>> 19) & 1; dest[destPos + 52] += (high >>> 20) & 1; dest[destPos + 53] += (high >>> 21) & 1; dest[destPos + 54] += (high >>> 22) & 1; dest[destPos + 55] += (high >>> 23) & 1; dest[destPos + 56] += (high >>> 24) & 1; dest[destPos + 57] += (high >>> 25) & 1; dest[destPos + 58] += (high >>> 26) & 1; dest[destPos + 59] += (high >>> 27) & 1; dest[destPos + 60] += (high >>> 28) & 1; dest[destPos + 61] += (high >>> 29) & 1; dest[destPos + 62] += (high >>> 30) & 1; dest[destPos + 63] += (high >>> 31) & 1; //[[Repeat.AutoGeneratedEnd]] destPos += 64; } int countFinish = count & 63; for (int destPosMax = destPos + countFinish; destPos < destPosMax; srcPos++, destPos++) { dest[destPos] += (int) ((src[(int) (srcPos >>> 6)] >>> (srcPos & 63)) & 1); } } /*Repeat.SectionStart fillBits*/ /** * Fills count bits in the packed dest array, starting * from the bit #destPos, * by the specified value. Be careful: the second int argument in this method * is the number of filled element, but not the end filled index * as in java.util.Arrays.fill methods. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param count the number of bits to be filled (must be >=0). * @param value new value of all filled bits (false means the bit 0, * true means the bit 1). * @throws NullPointerException if dest is {@code null}. * @throws IndexOutOfBoundsException if filling would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void fillBits(long[] dest, long destPos, long count, boolean value) { Objects.requireNonNull(dest, "Null dest"); int dPos = (int) (destPos >>> 6); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (cntStart > 0) { synchronized (dest) { if (value) dest[dPos] |= maskStart; else dest[dPos] &= ~maskStart; } count -= cntStart; dPos++; } long longValue = value ? -1 : 0; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++) { dest[dPos] = longValue; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { if (value) dest[dPos] |= maskFinish; else dest[dPos] &= ~maskFinish; } } } /** * Equivalent to {@link #fillBits(long[], long, long, boolean)} * method with the only exception, * that this method does not perform synchronization on dest array. * You may use this method instead of {@link #fillBits}, * if you are not planning to call it from different threads for the same dest array. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param count the number of bits to be filled (must be >=0). * @param value new value of all filled bits (false means the bit 0, * true means the bit 1). * @throws NullPointerException if dest is {@code null}. * @throws IndexOutOfBoundsException if filling would cause access of data outside array bounds. */ public static void fillBitsNoSync(long[] dest, long destPos, long count, boolean value) { Objects.requireNonNull(dest, "Null dest"); int dPos = (int) (destPos >>> 6); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (cntStart > 0) { if (value) dest[dPos] |= maskStart; else dest[dPos] &= ~maskStart; count -= cntStart; dPos++; } long longValue = value ? -1 : 0; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++) { dest[dPos] = longValue; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) if (value) dest[dPos] |= maskFinish; else dest[dPos] &= ~maskFinish; } } /*Repeat.SectionEnd fillBits*/ /** * Returns true if the specified fragment of the given packed bit array * is filled by zero bits (0). * Returns false if at least one of count bits of this array, * starting from the bit #pos, is 1. * *

If the count argument (number of elements) is 0, this method returns true. * * @param array the checked bit array (bits are packed in long values). * @param pos the initial index of the checked fragment in the array. * @param count the number of checked bits. * @return true if and only if all count bits, starting from the bit #pos, * are zero, or if count==0. * @throws NullPointerException if the array argument is {@code null}. * @throws IndexOutOfBoundsException if checking would cause access of data outside array bounds. */ public static boolean areBitsZero(long[] array, long pos, long count) { Objects.requireNonNull(array, "Null array"); int sPos = (int) (pos >>> 6); int sPosRem = (int) (pos & 63); int cntStart = (-sPosRem) & 63; long maskStart = -1L << sPosRem; // sPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (sPosRem + cntStart)) - 1; // &= sPosRem+cntStart times 1 (from the left) } if (cntStart > 0) { if ((array[sPos] & maskStart) != 0L) { return false; } count -= cntStart; sPos++; } for (int dPosMax = sPos + (int) (count >>> 6); sPos < dPosMax; sPos++) { if (array[sPos] != 0L) { return false; } } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) return (array[sPos] & maskFinish) == 0L; } return true; } /*Repeat.SectionStart logicalOperations*/ /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical NOT of corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it just inverts the specified bits. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void notBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart notBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] = (~src[sPos] & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] = ~src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = (~src[sPos] & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] = (~v & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] = ~((sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64)); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = (~v & maskFinish) | (dest[dPos] & ~maskFinish); } } } //[[Repeat.SectionEnd notBits_method_impl]] } /** * Equivalent to {@link #notBits(long[], long, long[], long, long) * notBits}(dest, destPos, dest, destPos, count). * * @param dest the source/destination array (bits are packed in long values). * @param destPos position of the first bit written in the source/destination array. * @param count the number of bits to be inverted (must be >=0). * @throws NullPointerException if dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ public static void notBits(long[] dest, long destPos, long count) { notBits(dest, destPos, dest, destPos, count); } /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical AND of them and corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it does nothing (so there are no reasons for this call). * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void andBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart andBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] &= src[sPos] | ~maskStart; } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] &= src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] &= src[sPos] | ~maskFinish; } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] &= v | ~maskStart; } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] &= (sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] &= v | ~maskFinish; } } } //[[Repeat.SectionEnd andBits_method_impl]] } /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical OR of them and corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it does nothing (so there are no reasons for this call). * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void orBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart orBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } // System.out.println((sPosRem == dPosRem ? "AORGOOD " : "AORBAD ") + sPosRem + "," + dPosRem); if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] |= src[sPos] & maskStart; } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] |= src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] |= src[sPos] & maskFinish; } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] |= v & maskStart; } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] |= (sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] |= v & maskFinish; } } } //[[Repeat.SectionEnd orBits_method_impl]] } /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical XOR of them and corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it clears all specified bits. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void xorBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart xorBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] = ((dest[dPos] ^ src[sPos]) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] ^= src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = ((dest[dPos] ^ src[sPos]) & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] = ((dest[dPos] ^ v) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] ^= (sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = ((dest[dPos] ^ v) & maskFinish) | (dest[dPos] & ~maskFinish); } } } //[[Repeat.SectionEnd xorBits_method_impl]] } /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical AND of them and inverted corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it clears all specified bits. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void andNotBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart andNotBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] = ((dest[dPos] & ~src[sPos]) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] &= ~src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = ((dest[dPos] & ~src[sPos]) & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] = ((dest[dPos] & ~v) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] &= ~((sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64)); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = ((dest[dPos] & ~v) & maskFinish) | (dest[dPos] & ~maskFinish); } } } //[[Repeat.SectionEnd andNotBits_method_impl]] } /** * Replaces count bits, * packed in dest array, starting from the bit #destPos, * with the logical OR of them and inverted corresponding count bits, * packed in src array, starting from the bit #srcPos. * *

This method works correctly even if src == dest * and srcPos == destPos: * in this case it sets all specified bits to 1. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void orNotBits(long[] dest, long destPos, long[] src, long srcPos, long count) { //[[Repeat.SectionStart orNotBits_method_impl]] Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } // System.out.println((sPosRem == dPosRem ? "AORGOOD " : "AORBAD ") + sPosRem + "," + dPosRem); if (sPosRem == dPosRem) { if (cntStart > 0) { synchronized (dest) { dest[dPos] = ((dest[dPos] | ~src[sPos]) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; dPos++; sPos++; } for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++, sPos++) { dest[dPos] |= ~src[sPos]; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = ((dest[dPos] | ~src[sPos]) & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { final int shift = dPosRem - sPosRem; long sNext; if (cntStart > 0) { long v; if (sPosRem + cntStart <= 64) { // cntStart bits are in a single src element if (shift > 0) v = (sNext = src[sPos]) << shift; else v = (sNext = src[sPos]) >>> -shift; sPosRem += cntStart; } else { v = (src[sPos] >>> -shift) | ((sNext = src[sPos + 1]) << (64 + shift)); sPos++; sPosRem = (sPosRem + cntStart) & 63; } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more synchronized (dest) { dest[dPos] = ((dest[dPos] | ~v) & maskStart) | (dest[dPos] & ~maskStart); } count -= cntStart; if (count == 0) { return; // little optimization } dPos++; } else { if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } sNext = src[sPos]; } // Now the bit #0 of dest[dPos] corresponds to the bit #sPosRem of src[sPos] final int sPosRem64 = 64 - sPosRem; for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; ) { sPos++; dest[dPos] |= ~((sNext >>> sPosRem) | ((sNext = src[sPos]) << sPosRem64)); dPos++; } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem + cntFinish <= 64) { // cntFinish bits are in a single src element v = sNext >>> sPosRem; } else { v = (sNext >>> sPosRem) | (src[sPos + 1] << sPosRem64); } synchronized (dest) { dest[dPos] = ((dest[dPos] | ~v) & maskFinish) | (dest[dPos] & ~maskFinish); } } } //[[Repeat.SectionEnd orNotBits_method_impl]] } /*Repeat.SectionEnd logicalOperations*/ /** * Reverse order of count bits, * packed in src array, starting from the bit #srcPos, * and puts the result into dest array, starting from the bit #destPos. * So, the bit #(destPos+k) in dest bit array will be equal to the bit * #(srcPos+count-1-k) of the src bit array. * *

This method does not work correctly if src == dest. * * @param dest the destination array (bits are packed in long values). * @param destPos position of the first bit written in the destination array. * @param src the source array (bits are packed in long values). * @param srcPos position of the first bit read in the source array. * @param count the number of bits to be replaced (must be >=0). * @throws NullPointerException if either src or dest is {@code null}. * @throws IndexOutOfBoundsException if accessing bits would cause access of data outside array bounds. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public static void reverseBits(long[] dest, long destPos, long[] src, long srcPos, long count) { Objects.requireNonNull(dest, "Null dest"); Objects.requireNonNull(src, "Null src"); if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } srcPos += count; int sPos = (int) (srcPos >>> 6); int dPos = (int) (destPos >>> 6); int sPosRem = (int) (srcPos & 63); int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (dPosRem + cntStart)) - 1; // &= dPosRem+cntStart times 1 (from the left) } if (cntStart > 0) { long v; if (sPosRem >= cntStart) { // cntStart bits are in a single src element v = src[sPos] >>> sPosRem - cntStart; sPosRem -= cntStart; } else { v = sPosRem == 0 ? // necessary check to avoid possible IndexOutOfBoundsException src[sPos - 1] >>> (64 - cntStart) : (src[sPos] << cntStart - sPosRem) | (src[sPos - 1] >>> (64 + sPosRem - cntStart)); sPos--; sPosRem = (sPosRem - cntStart) & 63; } // low cntStart bits of v contain the last cntStart bits of src v = Long.reverse(v) >>> 64 - cntStart; // low cntStart bits of v contain the first cntStart bits of the result (dest) synchronized (dest) { dest[dPos] = ((v << dPosRem) & maskStart) | (dest[dPos] & ~maskStart); } // let's suppose dPosRem = 0 now; don't perform it, because we'll not use dPosRem more count -= cntStart; if (count == 0) { return; // necessary check to avoid IndexOutOfBoundException while accessing src[sPos] } dPos++; } if (sPosRem == 0) { for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++) { sPos--; dest[dPos] = Long.reverse(src[sPos]); } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) synchronized (dest) { dest[dPos] = (Long.reverse(src[sPos - 1]) & maskFinish) | (dest[dPos] & ~maskFinish); } } } else { int sPosRem64 = 64 - sPosRem; long sNext = src[sPos]; // count > 0, so either this loop or the next loop will really work: src[sPos] must exist for (int dPosMax = dPos + (int) (count >>> 6); dPos < dPosMax; dPos++) { sPos--; dest[dPos] = Long.reverse((sNext << sPosRem64) | ((sNext = src[sPos]) >>> sPosRem)); } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) long v; if (sPosRem >= cntFinish) { // cntFinish bits are in a single src element v = sNext << sPosRem64; } else { v = (sNext << sPosRem64) | (src[sPos - 1] >>> sPosRem); } synchronized (dest) { dest[dPos] = (Long.reverse(v) & maskFinish) | (dest[dPos] & ~maskFinish); } } } } /** * Returns the minimal index k, so that lowIndex<=k<highIndex * and the bit #k in the packed src bit array is equal to value, * or -1 if there is no such bits. * *

If lowIndex>=highIndex, this method returns -1. * * @param src the searched packed bit array. * @param lowIndex the low index for search (inclusive). * @param highIndex the high index for search (exclusive). * @param value the value of bit to be found. * @return the index of the first occurrence of this bit in range lowIndex..highIndex-1, * or -1 if this bit does not occur * or if lowIndex>=highIndex. * @throws NullPointerException if array is {@code null}. * @throws IndexOutOfBoundsException if lowIndex is negative or * if highIndex is greater than src.length*64. * @see #lastIndexOfBit(long[], long, long, boolean) */ public static long indexOfBit(long[] src, long lowIndex, long highIndex, boolean value) { //[[Repeat.SectionStart indexOfBit_method_impl]] Objects.requireNonNull(src, "Null src"); if (lowIndex < 0) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: low index = " + lowIndex); } if (highIndex > ((long) src.length) << 6) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: high index = " + highIndex); } if (lowIndex >= highIndex) { return -1; } long count = highIndex - lowIndex; int sPos = (int) (lowIndex >>> 6); int sPosRem = (int) (lowIndex & 63); int cntStart = (-sPosRem) & 63; long fromAligned = lowIndex - sPosRem; long maskStart = -1L << sPosRem; // sPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (sPosRem + cntStart)) - 1; // &= sPosRem+cntStart times 1 (from the left) } if (cntStart > 0) { int index = Long.numberOfTrailingZeros((value ? src[sPos] : ~src[sPos]) & maskStart); if (index != 64) return fromAligned + index; count -= cntStart; sPos++; fromAligned += 64; } if (value) { for (int sPosMax = sPos + (int) (count >>> 6); sPos < sPosMax; sPos++, fromAligned += 64) { int index = Long.numberOfTrailingZeros(src[sPos]); if (index != 64) { return fromAligned + index; } } } else { for (int sPosMax = sPos + (int) (count >>> 6); sPos < sPosMax; sPos++, fromAligned += 64) { int index = Long.numberOfTrailingZeros(~src[sPos]); if (index != 64) { return fromAligned + index; } } } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) int index = Long.numberOfTrailingZeros((value ? src[sPos] : ~src[sPos]) & maskFinish); if (index != 64) { return fromAligned + index; } } return -1; //[[Repeat.SectionEnd indexOfBit_method_impl]] } /** * Returns the maximal index k, so that highIndex>k>=lowIndex * and the bit #k in the packed src bit array is equal to value, * or -1 if there is no such bits. * *

If highIndex<=lowIndex, this method returns -1. * *

Note that lowIndex and highIndex arguments have the same sense as in * {@link #indexOfBit(long[], long, long, boolean)} method: * they describe the search index range lowIndex<=k<highIndex. * * @param src the searched packed bit array. * @param lowIndex the low index in the array for search (inclusive); * pass 0 to search all remaining elements. * @param highIndex the high index in the array for search (exclusive). * @param value the value of bit to be found. * @return the index of the last occurrence of this bit in range lowIndex..highIndex-1, * or -1 if this bit does not occur * or if lowIndex>=highIndex. * @throws NullPointerException if src is {@code null}. * @throws IndexOutOfBoundsException if lowIndex is negative or * if highIndex is greater than src.length*64. * @see #indexOfBit(long[], long, long, boolean) */ public static long lastIndexOfBit(long[] src, long lowIndex, long highIndex, boolean value) { //[[Repeat.SectionStart lastIndexOfBit_method_impl]] Objects.requireNonNull(src, "Null src"); if (lowIndex < 0) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: low index = " + lowIndex); } if (highIndex > ((long) src.length) << 6) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: high index = " + highIndex); } if (lowIndex >= highIndex) { return -1; } long count = highIndex - lowIndex; int sPos = (int) ((highIndex - 1) >>> 6); int cntStart = ((int) highIndex) & 63; long fromAligned = ((highIndex - 1) & ~63) + 63; // 64k+63 long maskStart = (1L << cntStart) - 1; // cntStart times 1 (from the left) if (cntStart > count) { maskStart &= -1L << (cntStart - count); // &= cntStart-count times 0, then 1 (from the left) cntStart = (int) count; } if (cntStart > 0) { int index = Long.numberOfLeadingZeros((value ? src[sPos] : ~src[sPos]) & maskStart); if (index != 64) { return fromAligned - index; } count -= cntStart; sPos--; fromAligned -= 64; } if (value) { for (int sPosMin = sPos - (int) (count >>> 6); sPos > sPosMin; sPos--, fromAligned -= 64) { int index = Long.numberOfLeadingZeros(src[sPos]); if (index != 64) { return fromAligned - index; } } } else { for (int sPosMin = sPos - (int) (count >>> 6); sPos > sPosMin; sPos--, fromAligned -= 64) { int index = Long.numberOfLeadingZeros(~src[sPos]); if (index != 64) { return fromAligned - index; } } } int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = -1L << (64 - cntFinish); // cntFinish times 1 (from the right) int index = Long.numberOfLeadingZeros((value ? src[sPos] : ~src[sPos]) & maskFinish); if (index != 64) { return fromAligned - index; } } return -1; //[[Repeat.SectionEnd lastIndexOfBit_method_impl]] } /*Repeat.SectionStart cardinality*/ /** * Returns the number of high bits (1) in the given fragment of the given packed bit array. * * @param src the source packed bit array. * @param fromIndex the initial checked bit index in array, inclusive. * @param toIndex the end checked bit index in array, exclusive. * @return the number of high bits (1) in the given fragment of the given packed bit array. * @throws NullPointerException if the src argument is {@code null}. * @throws IndexOutOfBoundsException if fromIndex or toIndex are negative, * if toIndex is greater than src.length*64, * or if fromIndex is greater than startIndex */ public static long cardinality(long[] src, final long fromIndex, final long toIndex) { //[[Repeat.SectionStart cardinality_method_impl]] Objects.requireNonNull(src, "Null src argument in cardinality method"); if (fromIndex < 0) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: initial index = " + fromIndex); } if (toIndex > ((long) src.length) << 6) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: end index = " + toIndex); } if (fromIndex > toIndex) { throw new ArrayIndexOutOfBoundsException("Bit array index out of range: initial index = " + fromIndex + " > end index = " + toIndex); } long count = toIndex - fromIndex; int sPos = (int) (fromIndex >>> 6); int sPosRem = (int) (fromIndex & 63); int cntStart = (-sPosRem) & 63; long maskStart = -1L << sPosRem; // sPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = (int) count; maskStart &= (1L << (sPosRem + cntStart)) - 1; // &= sPosRem+cntStart times 1 (from the left) } long result = 0; if (cntStart > 0) { result += Long.bitCount(src[sPos] & maskStart); count -= cntStart; sPos++; } final int sPosMax = sPos + (int) (count >>> 6); result += bitCount(src, sPos, sPosMax); sPos = sPosMax; /* // The loop below is the 64-bit version of the algorithm published in // "Hacker's Delight" by Henry S. Warren, figure 5-4, // Addison-Wesley Publishing Company, Inc., 2002. // In new JVM, this is usually a bad idea, because // Long.bitCount is an intrinsic candidate and works faster on most CPU. for (int sPosMax = sPos + (int) (count >>> 6); sPos < sPosMax; ) { long s8 = 0; for (int lim = Math.min(sPosMax, sPos + 31); sPos < lim; sPos++) { // maximal intermediate sums (bit counts in bytes) are 8, // so 31 iterations do not lead to overflow (8*31<256) long value = src[sPos]; value -= (value >>> 1) & 0x5555555555555555L; value = (value & 0x3333333333333333L) + ((value >>> 2) & 0x3333333333333333L); s8 += (value + (value >>> 4)) & 0x0F0F0F0F0F0F0F0FL; } s8 = (s8 & 0x00FF00FF00FF00FFL) + ((s8 >>> 8) & 0x00FF00FF00FF00FFL); s8 = (s8 & 0x0000FFFF0000FFFFL) + ((s8 >>> 16) & 0x0000FFFF0000FFFFL); result += ((int) s8 + (int) (s8 >>> 32)) & 0xFFFF; } */ int cntFinish = (int) (count & 63); if (cntFinish > 0) { long maskFinish = (1L << cntFinish) - 1; // cntFinish times 1 (from the left) result += Long.bitCount(src[sPos] & maskFinish); } return result; //[[Repeat.SectionEnd cardinality_method_impl]] } static long bitCount(long[] src, int from, int to) { long result = 0; for (int i = from; i < to; i++) { result += Long.bitCount(src[i]); } return result; } /*Repeat.SectionEnd cardinality*/ static long getBits64Impl(long[] src, long srcPos, int count) { final long srcPosDiv64 = srcPos >>> 6; if (count == 0 || srcPosDiv64 >= src.length) { return 0; } int sPosRem = (int) (srcPos & 63); int sPos = (int) srcPosDiv64; int bitsLeft = 64 - sPosRem; // Below is a simplified implementation of PackedBitArraysPer8.getBits for a case of maximum 2 iterations if (count > bitsLeft) { final long actualBitsLow = src[sPos] >>> sPosRem; sPos++; if (sPos >= src.length) { return actualBitsLow; } final long actualBitsHigh = src[sPos] & (-1L >>> 64 - (count - bitsLeft)); return actualBitsLow | (actualBitsHigh << bitsLeft); } else { return (src[sPos] & (-1L >>> (bitsLeft - count))) >>> sPosRem; } } static void setBits64Impl(long[] dest, long destPos, long bits, int count) { final long destPosDiv64 = destPos >>> 6; if (count == 0 || destPosDiv64 >= dest.length) { return; } int dPosRem = (int) (destPos & 63); int cntStart = (-dPosRem) & 63; long maskStart = -1L << dPosRem; // dPosRem times 0, then 1 (from the left) if (cntStart > count) { cntStart = count; maskStart &= (1L << (dPosRem + count)) - 1; // &= dPosRem+cntStart times 1 (from the left) } int dPos = (int) destPosDiv64; if (cntStart > 0) { dest[dPos] = ((bits << dPosRem) & maskStart) | (dest[dPos] & ~maskStart); dPos++; count -= cntStart; bits >>>= cntStart; } if (count > 0 && dPos < dest.length) { long maskFinish = (2L << (count - 1)) - 1; // count times 1 (from the left) dest[dPos] = (bits & maskFinish) | (dest[dPos] & ~maskFinish); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy