package com.jme3.util; /** * The wrapper for the primitive type {@code int}. *
* As with the specification, this implementation relies on code laid out in Henry S. Warren, Jr.'s Hacker's * Delight, (Addison Wesley, 2002) as well as The Aggregate's Magic Algorithms. * * @see java.lang.Number * @since 1.1 */ public final class FastInteger { /** * Constant for the maximum {@code int} value, 231-1. */ public static final int MAX_VALUE = 0x7FFFFFFF; /** * Constant for the minimum {@code int} value, -231. */ public static final int MIN_VALUE = 0x80000000; /** * Constant for the number of bits needed to represent an {@code int} in * two's complement form. * * @since 1.5 */ public static final int SIZE = 32; /* * Progressively smaller decimal order of magnitude that can be represented * by an instance of Integer. Used to help compute the String * representation. */ private static final int[] decimalScale = new int[] { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; /** * Converts the specified integer into its decimal string representation. * The returned string is a concatenation of a minus sign if the number is * negative and characters from '0' to '9'. * * @param value * the integer to convert. * @return the decimal string representation of {@code value}. */ public static boolean toCharArray(int value, char[] output) { if (value == 0) { output[0] = '0'; output[1] = 0; return true; } // Faster algorithm for smaller Integers if (value < 1000 && value > -1000) { int positive_value = value < 0 ? -value : value; int first_digit = 0; if (value < 0) { output[0] = '-'; first_digit++; } int last_digit = first_digit; int quot = positive_value; do { int res = quot / 10; int digit_value = quot - ((res << 3) + (res << 1)); digit_value += '0'; output[last_digit++] = (char) digit_value; quot = res; } while (quot != 0); int count = last_digit--; do { char tmp = output[last_digit]; output[last_digit--] = output[first_digit]; output[first_digit++] = tmp; } while (first_digit < last_digit); output[count] = 0; return true; } if (value == MIN_VALUE) { System.arraycopy("-2147483648".toCharArray(), 0, output, 0, 12); output[12] = 0; return true; } int positive_value = value < 0 ? -value : value; byte first_digit = 0; if (value < 0) { output[0] = '-'; first_digit++; } byte last_digit = first_digit; byte count; int number; boolean start = false; for (int i = 0; i < 9; i++) { count = 0; if (positive_value < (number = decimalScale[i])) { if (start) { output[last_digit++] = '0'; } continue; } if (i > 0) { number = (decimalScale[i] << 3); if (positive_value >= number) { positive_value -= number; count += 8; } number = (decimalScale[i] << 2); if (positive_value >= number) { positive_value -= number; count += 4; } } number = (decimalScale[i] << 1); if (positive_value >= number) { positive_value -= number; count += 2; } if (positive_value >= decimalScale[i]) { positive_value -= decimalScale[i]; count++; } if (count > 0 && !start) { start = true; } if (start) { output[last_digit++] = (char) (count + '0'); } } output[last_digit++] = (char) (positive_value + '0'); output[last_digit] = 0; count = last_digit--; return true; } /** * Determines the highest (leftmost) bit of the specified integer that is 1 * and returns the bit mask value for that bit. This is also referred to as * the Most Significant 1 Bit. Returns zero if the specified integer is * zero. * * @param i * the integer to examine. * @return the bit mask indicating the highest 1 bit in {@code i}. * @since 1.5 */ public static int highestOneBit(int i) { i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return (i & ~(i >>> 1)); } /** * Determines the lowest (rightmost) bit of the specified integer that is 1 * and returns the bit mask value for that bit. This is also referred * to as the Least Significant 1 Bit. Returns zero if the specified integer * is zero. * * @param i * the integer to examine. * @return the bit mask indicating the lowest 1 bit in {@code i}. * @since 1.5 */ public static int lowestOneBit(int i) { return (i & (-i)); } /** * Determines the number of leading zeros in the specified integer prior to * the {@link #highestOneBit(int) highest one bit}. * * @param i * the integer to examine. * @return the number of leading zeros in {@code i}. * @since 1.5 */ public static int numberOfLeadingZeros(int i) { i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; return bitCount(~i); } /** * Determines the number of trailing zeros in the specified integer after * the {@link #lowestOneBit(int) lowest one bit}. * * @param i * the integer to examine. * @return the number of trailing zeros in {@code i}. * @since 1.5 */ public static int numberOfTrailingZeros(int i) { return bitCount((i & -i) - 1); } /** * Counts the number of 1 bits in the specified integer; this is also * referred to as population count. * * @param i * the integer to examine. * @return the number of 1 bits in {@code i}. * @since 1.5 */ public static int bitCount(int i) { i -= ((i >> 1) & 0x55555555); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); i = (((i >> 4) + i) & 0x0F0F0F0F); i += (i >> 8); i += (i >> 16); return (i & 0x0000003F); } /** * Rotates the bits of the specified integer to the left by the specified * number of bits. * * @param i * the integer value to rotate left. * @param distance * the number of bits to rotate. * @return the rotated value. * @since 1.5 */ public static int rotateLeft(int i, int distance) { if (distance == 0) { return i; } /* * According to JLS3, 15.19, the right operand of a shift is always * implicitly masked with 0x1F, which the negation of 'distance' is * taking advantage of. */ return ((i << distance) | (i >>> (-distance))); } /** * Rotates the bits of the specified integer to the right by the specified * number of bits. * * @param i * the integer value to rotate right. * @param distance * the number of bits to rotate. * @return the rotated value. * @since 1.5 */ public static int rotateRight(int i, int distance) { if (distance == 0) { return i; } /* * According to JLS3, 15.19, the right operand of a shift is always * implicitly masked with 0x1F, which the negation of 'distance' is * taking advantage of. */ return ((i >>> distance) | (i << (-distance))); } /** * Reverses the order of the bytes of the specified integer. * * @param i * the integer value for which to reverse the byte order. * @return the reversed value. * @since 1.5 */ public static int reverseBytes(int i) { int b3 = i >>> 24; int b2 = (i >>> 8) & 0xFF00; int b1 = (i & 0xFF00) << 8; int b0 = i << 24; return (b0 | b1 | b2 | b3); } /** * Reverses the order of the bits of the specified integer. * * @param i * the integer value for which to reverse the bit order. * @return the reversed value. * @since 1.5 */ public static int reverse(int i) { // From Hacker's Delight, 7-1, Figure 7-1 i = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555; i = (i & 0x33333333) << 2 | (i >> 2) & 0x33333333; i = (i & 0x0F0F0F0F) << 4 | (i >> 4) & 0x0F0F0F0F; return reverseBytes(i); } /** * Returns the value of the {@code signum} function for the specified * integer. * * @param i * the integer value to check. * @return -1 if {@code i} is negative, 1 if {@code i} is positive, 0 if * {@code i} is zero. * @since 1.5 */ public static int signum(int i) { return (i == 0 ? 0 : (i < 0 ? -1 : 1)); } /** * Returns a {@code Integer} instance for the specified integer value. *
* If it is not necessary to get a new {@code Integer} instance, it is * recommended to use this method instead of the constructor, since it * maintains a cache of instances which may result in better performance. * * @param i * the integer value to store in the instance. * @return a {@code Integer} instance containing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { if (i < -128 || i > 127) { return new Integer(i); } return valueOfCache.CACHE [i+128]; } static class valueOfCache { /** *
* A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing. */ static final Integer[] CACHE = new Integer[256]; static { for(int i=-128; i<=127; i++) { CACHE[i+128] = new Integer(i); } } } }