--- old/src/share/classes/java/lang/Integer.java 2012-01-17 18:52:29.000000000 -0800 +++ new/src/share/classes/java/lang/Integer.java 2012-01-17 18:52:29.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +128,6 @@ * @see java.lang.Character#MIN_RADIX */ public static String toString(int i, int radix) { - if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; @@ -159,6 +158,35 @@ } /** + * Returns an unsigned string representation of the first argument + * in the radix specified by the second argument. + * + *

If the radix is smaller than {@code Character.MIN_RADIX} + * or larger than {@code Character.MAX_RADIX}, then the radix + * {@code 10} is used instead. + * + *

Note that since the first argument is treated as an unsigned + * value, no leading sign character is printed. + * + *

If the magnitude is zero, it is represented by a single zero + * character {@code '0'} ('\u0030'); otherwise, + * the first character of the representation of the magnitude will + * not be the zero character. + * + *

The characters used as digits and the behavior of radixes + * is the same as {@link #toString(int, int) toString}. + * + * @param i an integer to be converted to an unsigned string. + * @param radix the radix to use in the string representation. + * @return an unsigned string representation of the argument in the specified radix. + * @see #toString(int, int) + * @since 1.8 + */ + public static String toUnsignedString(int i, int radix) { + return Long.toString(toUnsignedLong(i), radix); + } + + /** * Returns a string representation of the integer argument as an * unsigned integer in base 16. * @@ -166,12 +194,18 @@ * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in hexadecimal (base 16) with no extra leading - * {@code 0}s. If the unsigned magnitude is zero, it is - * represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as - * hexadecimal digits: + * {@code 0}s. + * + *

The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 16)}. + * + *

If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ('\u0030'); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as hexadecimal digits: * *

* {@code 0123456789abcdef} @@ -190,10 +224,12 @@ * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in hexadecimal (base 16). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toHexString(int i) { - return toUnsignedString(i, 4); + return toUnsignedString0(i, 4); } /** @@ -205,12 +241,16 @@ * argument. This value is converted to a string of ASCII digits * in octal (base 8) with no extra leading {@code 0}s. * + *

The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 8)}. + * *

If the unsigned magnitude is zero, it is represented by a - * single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as octal - * digits: + * single zero character {@code '0'} ('\u0030'); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as octal digits: * *

* {@code 01234567} @@ -222,10 +262,12 @@ * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in octal (base 8). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toOctalString(int i) { - return toUnsignedString(i, 3); + return toUnsignedString0(i, 3); } /** @@ -236,27 +278,34 @@ * if the argument is negative; otherwise it is equal to the * argument. This value is converted to a string of ASCII digits * in binary (base 2) with no extra leading {@code 0}s. - * If the unsigned magnitude is zero, it is represented by a - * single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The characters {@code '0'} - * ('\u0030') and {@code '1'} - * ('\u0031') are used as binary digits. + * + *

The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 2)}. + * + *

If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ('\u0030'); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * characters {@code '0'} ('\u0030') and {@code + * '1'} ('\u0031') are used as binary digits. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in binary (base 2). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toBinaryString(int i) { - return toUnsignedString(i, 1); + return toUnsignedString0(i, 1); } /** * Convert the integer to an unsigned number. */ - private static String toUnsignedString(int i, int shift) { + private static String toUnsignedString0(int i, int shift) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift; @@ -335,6 +384,23 @@ } /** + * Returns an unsigned string representation of the argument. + * + * The argument is converted to unsigned decimal representation + * and returned as a string exactly as if the argument and radix + * 10 were given as arguments to the {@link #toUnsignedString(int, + * int)} method. + * + * @param i an integer to be converted to an unsigned string. + * @return an unsigned string representation of the argument. + * @see #toUnsignedString(int, int) + * @since 1.8 + */ + public static String toUnsignedString(int i) { + return Long.toString(toUnsignedLong(i)); + } + + /** * Places characters representing the integer i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant @@ -529,6 +595,100 @@ } /** + * Parses the string argument as an unsigned integer in the radix + * specified by the second argument. + * + * The characters in the string must all be digits of the + * specified radix (as determined by whether {@link + * java.lang.Character#digit(char, int)} returns a nonnegative + * value), except that the first character may be an ASCII plus + * sign {@code '+'} ('\u002B'). The resulting + * integer value is returned. + * + *

An exception of type {@code NumberFormatException} is + * thrown if any of the following situations occurs: + *

+ * + * + * @param s the {@code String} containing the unsigned integer + * representation to be parsed + * @param radix the radix to be used while parsing {@code s}. + * @return the integer represented by the string argument in the + * specified radix. + * @throws NumberFormatException if the {@code String} + * does not contain a parsable {@code int}. + * @since 1.8 + */ + public static int parseUnsignedInt(String s, int radix) + throws NumberFormatException { + if (s == null) { + throw new NumberFormatException("null"); + } + + int len = s.length(); + if (len > 0) { + char firstChar = s.charAt(0); + if (firstChar == '-') { + throw new + NumberFormatException(String.format("Illegal leading minus sign " + + "on unsigned string %s.", s)); + } else { + if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits + (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits + return parseInt(s, radix); + } else { + long ell = Long.parseLong(s, radix); + if ((ell & 0xffff_ffff_0000_0000L) == 0) { + return (int) ell; + } else { + throw new + NumberFormatException(String.format("String value %s exceeds " + + "range of unsigned int.", s)); + } + } + } + } else { + throw NumberFormatException.forInputString(s); + } + } + + /** + * Parses the string argument as an unsigned decimal integer. The + * characters in the string must all be decimal digits, except + * that the first character may be an an ASCII plus sign {@code + * '+'} ('\u002B'). The resulting integer value + * is returned, exactly as if the argument and the radix 10 were + * given as arguments to the {@link + * #parseUnsignedInt(java.lang.String, int)} method. + * + * @param s a {@code String} containing the unsigned {@code int} + * representation to be parsed + * @return the unsigned integer value represented by the argument in decimal. + * @throws NumberFormatException if the string does not contain a + * parsable unsigned integer. + * @since 1.8 + */ + public static int parseUnsignedInt(String s) throws NumberFormatException { + return parseUnsignedInt(s, 10); + } + + /** * Returns an {@code Integer} object holding the value * extracted from the specified {@code String} when parsed * with the radix given by the second argument. The first argument @@ -1030,6 +1190,76 @@ return (x < y) ? -1 : ((x == y) ? 0 : 1); } + /** + * Compares two {@code int} values numerically treating the values + * as unsigned. + * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + * @since 1.8 + */ + public static int compareUnsigned(int x, int y) { + return compare(x + MIN_VALUE, y + MIN_VALUE); + } + + /** + * Converts the argument to a {@code long} by an unsigned + * conversion. In an unsigned conversion to a {@code long}, the + * high-order 32 bits of the {@code long} are zero and the + * low-order 32 bits are equal to the bits of the integer + * argument. + * + * @return the argument converted to {@code long} by an unsigned + * conversion + * @param x the value to convert to an unsigned {@code long} + * @since 1.8 + */ + public static long toUnsignedLong(int x) { + return ((long) x) & 0xffffffffL; + } + + /** + * Returns the unsigned quotient of dividing the first argument by + * the second where each argument is interpreted as an unsigned + * value. + * + * In other words, return the unsigned value of {@code + * (dividend / divisor)}. + * + * @return the unsigned quotient of the first argument divided by + * the second argument + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @since 1.8 + */ + public static int divideUnsigned(int dividend, int divisor) { + // In lieu of tricky code, for now just use long arithmetic. + return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor)); + } + + /** + * Returns the unsigned remainder from dividing the first argument by + * the second where each argument is interpreted as an unsigned + * value. + * + * In other words, return the unsigned value of {@code + * (dividend % divisor)}. + * + * @return the unsigned remainder of the first argument divided by + * the second argument + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @since 1.8 + */ + public static int remainderUnsigned(int dividend, int divisor) { + // In lieu of tricky code, for now just use long arithmetic. + return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor)); + } + // Bit twiddling