Index: C:/Documents and Settings/Nathan/ws/luni/src/main/java/java/lang/Long.java =================================================================== --- C:/Documents and Settings/Nathan/ws/luni/src/main/java/java/lang/Long.java (revision 383745) +++ C:/Documents and Settings/Nathan/ws/luni/src/main/java/java/lang/Long.java (working copy) @@ -15,9 +15,20 @@ package java.lang; - /** - * Integers are objects (i.e. non-base types) which represent long values. + *

+ * Long is the wrapper for the primitive type long. + *

+ * + *

+ * As with the specification, this implementation relied 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.0 */ public final class Long extends Number implements Comparable { @@ -26,14 +37,21 @@ /** * The value which the receiver represents. */ - final long value; + private final long value; - /** - * Most positive and most negative possible long values. - */ - public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFl; + /** + *

+ * Constant for the maximum long value, 263-1. + *

+ */ + public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFL; - public static final long MIN_VALUE = 0x8000000000000000l; + /** + *

+ * Constant for the minimum long value, -231. + *

+ */ + public static final long MIN_VALUE = 0x8000000000000000L; /** * The java.lang.Class that represents this class. @@ -43,8 +61,25 @@ // Note: This can't be set to "long.class", since *that* is // defined to be "java.lang.Long.TYPE"; + /** + *

+ * Constant for the number of bits to represent a long in + * two's compliment form. + *

+ * + * @since 1.5 + */ + public static final int SIZE = 64; + + /** + *

+ * A cache of instances used by {@link #valueOf(long)} and auto-boxing. + *

+ */ + private static final Long[] CACHE = new Long[256]; + /** - * Constructs a new instance of the receiver which represents the int valued + * Constructs a new instance of the receiver which represents the long valued * argument. * * @param value @@ -90,10 +125,10 @@ * or decimal ("...") representation of a long. * * @param string - * a string representation of an int quantity. + * a string representation of an long quantity. * @return Long the value represented by the argument * @exception NumberFormatException - * if the argument could not be parsed as an int quantity. + * if the argument could not be parsed as an long quantity. */ public static Long decode(String string) throws NumberFormatException { int length = string.length(), i = 0; @@ -110,7 +145,7 @@ int base = 10; if (firstDigit == '0') { if (++i == length) - return new Long(0L); + return valueOf(0L); if ((firstDigit = string.charAt(i)) == 'x' || firstDigit == 'X') { if (i == length) throw new NumberFormatException(string); @@ -127,7 +162,7 @@ } long result = parse(string, i, base, negative); - return new Long(result); + return valueOf(result); } /** @@ -191,7 +226,7 @@ /** * Answers a Long representing the long value of the property named by the * argument. If the property could not be found, or its value could not be - * parsed as a long, answer a Long reperesenting the second argument. + * parsed as a long, answer a Long representing the second argument. * * @param string * The name of the desired long property. @@ -199,14 +234,14 @@ */ public static Long getLong(String string, long defaultValue) { if (string == null || string.length() == 0) - return new Long(defaultValue); + return valueOf(defaultValue); String prop = System.getProperty(string); if (prop == null) - return new Long(defaultValue); + return valueOf(defaultValue); try { return decode(prop); } catch (NumberFormatException ex) { - return new Long(defaultValue); + return valueOf(defaultValue); } } @@ -497,7 +532,7 @@ * if the argument could not be parsed as an long quantity. */ public static Long valueOf(String string) throws NumberFormatException { - return new Long(parseLong(string)); + return valueOf(parseLong(string)); } /** @@ -516,6 +551,219 @@ */ public static Long valueOf(String string, int radix) throws NumberFormatException { - return new Long(parseLong(string, radix)); + return valueOf(parseLong(string, radix)); } + + /** + *

+ * Determines the highest (leftmost) bit that is 1 and returns the value + * that is the bit mask for that bit. This is sometimes referred to as the + * Most Significant 1 Bit. + *

+ * + * @param lng The long to interrogate. + * @return The bit mask indicating the highest 1 bit. + * @since 1.5 + */ + public static long highestOneBit(long lng) { + lng |= (lng >> 1); + lng |= (lng >> 2); + lng |= (lng >> 4); + lng |= (lng >> 8); + lng |= (lng >> 16); + lng |= (lng >> 32); + return (lng & ~(lng >>> 1)); + } + + /** + *

+ * Determines the lowest (rightmost) bit that is 1 and returns the value + * that is the bit mask for that bit. This is sometimes referred to as the + * Least Significant 1 Bit. + *

+ * + * @param lng The long to interrogate. + * @return The bit mask indicating the lowest 1 bit. + * @since 1.5 + */ + public static long lowestOneBit(long lng) { + return (lng & (-lng)); + } + + /** + *

+ * Determines the number of leading zeros in the long passed + * prior to the {@link #highestOneBit(long) highest one bit}. + *

+ * + * @param lng The long to process. + * @return The number of leading zeros. + * @since 1.5 + */ + public static int numberOfLeadingZeros(long lng) { + lng |= lng >> 1; + lng |= lng >> 2; + lng |= lng >> 4; + lng |= lng >> 8; + lng |= lng >> 16; + lng |= lng >> 32; + return bitCount(~lng); + } + + /** + *

+ * Determines the number of trailing zeros in the long passed + * after the {@link #lowestOneBit(long) lowest one bit}. + *

+ * + * @param lng The long to process. + * @return The number of trailing zeros. + * @since 1.5 + */ + public static int numberOfTrailingZeros(long lng) { + return bitCount((lng & -lng) - 1); + } + + /** + *

+ * Counts the number of 1 bits in the long value passed; this + * is sometimes referred to as a population count. + *

+ * + * @param lng The long value to process. + * @return The number of 1 bits. + * @since 1.5 + */ + public static int bitCount(long lng) { + lng = (lng & 0x5555555555555555L) + ((lng >> 1) & 0x5555555555555555L); + lng = (lng & 0x3333333333333333L) + ((lng >> 2) & 0x3333333333333333L); + // adjust for 64-bit integer + int i = (int) ((lng >>> 32) + lng); + i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F); + i = (i & 0x00FF00FF) + ((i >> 8) & 0x00FF00FF); + i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF); + return i; + } + + /** + *

+ * Rotates the bits of lng to the left by the + * distance bits. + *

+ * + * @param lng The long value to rotate left. + * @param distance The number of bits to rotate. + * @return The rotated value. + * @since 1.5 + */ + public static long rotateLeft(long lng, int distance) { + if (distance == 0) + return lng; + /* + * According to JLS3, 15.19, the right operand of a shift is always + * implicitly masked with 0x3F, which the negation of 'distance' is + * taking advantage of. + */ + return ((lng << distance) | (lng >>> (-distance))); + } + + /** + *

+ * Rotates the bits of lng to the right by the + * distance bits. + *

+ * + * @param lng The long value to rotate right. + * @param distance The number of bits to rotate. + * @return The rotated value. + * @since 1.5 + */ + public static long rotateRight(long lng, int distance) { + if (distance == 0) + return lng; + /* + * According to JLS3, 15.19, the right operand of a shift is always + * implicitly masked with 0x3F, which the negation of 'distance' is + * taking advantage of. + */ + return ((lng >>> distance) | (lng << (-distance))); + } + + /** + *

+ * Reverses the bytes of a long. + *

+ * + * @param lng The long to reverse. + * @return The reversed value. + * @since 1.5 + */ + public static long reverseBytes(long lng) { + long b7 = lng >>> 56; + long b6 = (lng >>> 40) & 0xFF00L; + long b5 = (lng >>> 24) & 0xFF0000L; + long b4 = (lng >>> 8) & 0xFF000000L; + long b3 = (lng & 0xFF000000L) << 8; + long b2 = (lng & 0xFF0000L) << 24; + long b1 = (lng & 0xFF00L) << 40; + long b0 = lng << 56; + return (b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7); + } + + /** + *

+ * Reverses the bytes of a long. + *

+ * + * @param lng The long to reverse. + * @return The reversed value. + * @since 1.5 + */ + public static long reverse(long lng) { + // From Hacker's Delight, 7-1, Figure 7-1 + lng = (lng & 0x5555555555555555L) << 1 | (lng >> 1) + & 0x5555555555555555L; + lng = (lng & 0x3333333333333333L) << 2 | (lng >> 2) + & 0x3333333333333333L; + lng = (lng & 0x0F0F0F0F0F0F0F0FL) << 4 | (lng >> 4) + & 0x0F0F0F0F0F0F0F0FL; + return reverseBytes(lng); + } + + /** + *

+ * The signum function for long values. This + * method returns -1 for negative values, 1 for positive values and 0 for + * the value 0. + *

+ * + * @param lng The long value. + * @return -1 if negative, 1 if positive otherwise 0. + * @since 1.5 + */ + public static int signum(long lng) { + return (lng == 0 ? 0 : (lng < 0 ? -1 : 1)); + } + + /** + *

+ * Returns a Long instance for the long value + * passed. This method is preferred over the constructor, as this method may + * maintain a cache of instances. + *

+ * + * @param lng The long value. + * @return A Long instance. + * @since 1.5 + */ + public static Long valueOf(long lng) { + if (lng < -128 || lng > 127) { + return new Long(lng); + } + synchronized (CACHE) { + int idx = 128 + (int) lng; // 128 matches a cache size of 256 + Long result = CACHE[idx]; + return (result == null ? CACHE[idx] = new Long(lng) : result); + } + } }