/*
* Copyright ( c ) 1994 , 2023 , 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
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
package java.lang;
import jdk.internal.misc.CDS;
import jdk.internal.misc.VM;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import java.lang.annotation.Native ;
import java.lang.constant.Constable;
import java.lang.constant.ConstantDesc;
import java.lang.invoke.MethodHandles;
import java.util.Objects;
import java.util.Optional;
import static java.lang.String.COMPACT_STRINGS;
import static java.lang.String.LATIN1;
import static java.lang.String.UTF16;
/**
* The { @ code Integer } class wraps a value of the primitive type
* { @ code int } in an object . An object of type { @ code Integer }
* contains a single field whose type is { @ code int } .
*
* < p > In addition , this class provides several methods for converting
* an { @ code int } to a { @ code String } and a { @ code String } to an
* { @ code int } , as well as other constants and methods useful when
* dealing with an { @ code int } .
*
* < p > This is a < a href = " { @ docRoot } / java . base / java / lang / doc - files / ValueBased . html " > value - based < / a >
* class ; programmers should treat instances that are
* { @ linkplain # equals ( Object ) equal } as interchangeable and should not
* use instances for synchronization , or unpredictable behavior may
* occur . For example , in a future release , synchronization may fail .
*
* < p > Implementation note : The implementations of the " bit twiddling "
* methods ( such as { @ link # highestOneBit ( int ) highestOneBit } and
* { @ link # numberOfTrailingZeros ( int ) numberOfTrailingZeros } ) are
* based on material from Henry S . Warren , Jr . ' s < i > Hacker ' s
* Delight < / i > , ( Addison Wesley , 2002 ) .
*
* @ author Lee Boynton
* @ author Arthur van Hoff
* @ author Josh Bloch
* @ author Joseph D . Darcy
* @ since 1 . 0
*/
@jdk.internal.ValueBased
public final class Integer extends Number
implements Comparable<Integer>, Constable, ConstantDesc {
/**
* A constant holding the minimum value an { @ code int } can
* have , - 2 < sup > 31 < / sup > .
*/
@Native public static final int MIN_VALUE = 0 x80000000;
/**
* A constant holding the maximum value an { @ code int } can
* have , 2 < sup > 31 < / sup > - 1 .
*/
@Native public static final int MAX_VALUE = 0 x7fffffff;
/**
* The { @ code Class } instance representing the primitive type
* { @ code int } .
*
* @ since 1 . 1
*/
@SuppressWarnings("unchecked" )
public static final Class <Integer> TYPE = (Class <Integer>) Class .getPrimitiveClass("int" );
/**
* All possible chars for representing a number as a String
*/
static final char [] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
/**
* Returns a string representation of the first argument in the
* radix specified by the second argument .
*
* < p > 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 .
*
* < p > If the first argument is negative , the first element of the
* result is the ASCII minus character { @ code ' - ' }
* ( { @ code ' \ u005Cu002D ' } ) . If the first argument is not
* negative , no sign character appears in the result .
*
* < p > The remaining characters of the result represent the magnitude
* of the first argument . If the magnitude is zero , it is
* represented by a single zero character { @ code ' 0 ' }
* ( { @ code ' \ u005Cu0030 ' } ) ; otherwise , the first character of
* the representation of the magnitude will not be the zero
* character . The following ASCII characters are used as digits :
*
* < blockquote >
* { @ code 0123456789 abcdefghijklmnopqrstuvwxyz }
* < / blockquote >
*
* These are { @ code ' \ u005Cu0030 ' } through
* { @ code ' \ u005Cu0039 ' } and { @ code ' \ u005Cu0061 ' } through
* { @ code ' \ u005Cu007A ' } . If { @ code radix } is
* < var > N < / var > , then the first < var > N < / var > of these characters
* are used as radix - < var > N < / var > digits in the order shown . Thus ,
* the digits for hexadecimal ( radix 16 ) are
* { @ code 0123456789 abcdef } . If uppercase letters are
* desired , the { @ link java . lang . String # toUpperCase ( ) } method may
* be called on the result :
*
* < blockquote >
* { @ code Integer . toString ( n , 16 ) . toUpperCase ( ) }
* < / blockquote >
*
* @ param i an integer to be converted to a string .
* @ param radix the radix to use in the string representation .
* @ return a string representation of the argument in the specified radix .
* @ see java . lang . Character # MAX_RADIX
* @ 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 ;
/* Use the faster version */
if (radix == 10 ) {
return toString(i);
}
if (COMPACT_STRINGS) {
byte [] buf = new byte [33 ];
boolean negative = (i < 0 );
int charPos = 32 ;
if (!negative) {
i = -i;
}
while (i <= -radix) {
buf[charPos--] = (byte )digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = (byte )digits[-i];
if (negative) {
buf[--charPos] = '-' ;
}
return StringLatin1.newString(buf, charPos, (33 - charPos));
}
return toStringUTF16(i, radix);
}
private static String toStringUTF16(int i, int radix) {
byte [] buf = new byte [33 * 2 ];
boolean negative = (i < 0 );
int charPos = 32 ;
if (!negative) {
i = -i;
}
while (i <= -radix) {
StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]);
i = i / radix;
}
StringUTF16.putChar(buf, charPos, digits[-i]);
if (negative) {
StringUTF16.putChar(buf, --charPos, '-' );
}
return StringUTF16.newString(buf, charPos, (33 - charPos));
}
/**
* Returns a string representation of the first argument as an
* unsigned integer value in the radix specified by the second
* argument .
*
* < p > 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 .
*
* < p > Note that since the first argument is treated as an unsigned
* value , no leading sign character is printed .
*
* < p > If the magnitude is zero , it is represented by a single zero
* character { @ code ' 0 ' } ( { @ code ' \ u005Cu0030 ' } ) ; otherwise ,
* the first character of the representation of the magnitude will
* not be the zero character .
*
* < p > The behavior of radixes and the characters used as digits
* are 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 .toUnsignedString(toUnsignedLong(i), radix);
}
/**
* Returns a string representation of the integer argument as an
* unsigned integer in base & nbsp ; 16 .
*
* < p > The unsigned integer value is the argument plus 2 < sup > 32 < / sup >
* 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 & nbsp ; 16 ) with no extra leading
* { @ code 0 } s .
*
* < p > 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 ) } .
*
* < p > If the unsigned magnitude is zero , it is represented by a
* single zero character { @ code ' 0 ' } ( { @ code ' \ u005Cu0030 ' } ) ;
* 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 :
*
* < blockquote >
* { @ code 0123456789 abcdef }
* < / blockquote >
*
* These are the characters { @ code ' \ u005Cu0030 ' } through
* { @ code ' \ u005Cu0039 ' } and { @ code ' \ u005Cu0061 ' } through
* { @ code ' \ u005Cu0066 ' } . If uppercase letters are
* desired , the { @ link java . lang . String # toUpperCase ( ) } method may
* be called on the result :
*
* < blockquote >
* { @ code Integer . toHexString ( n ) . toUpperCase ( ) }
* < / blockquote >
*
* @ apiNote
* The { @ link java . util . HexFormat } class provides formatting and parsing
* of byte arrays and primitives to return a string or adding to an { @ link Appendable } .
* { @ code HexFormat } formats and parses uppercase or lowercase hexadecimal characters ,
* with leading zeros and for byte arrays includes for each byte
* a delimiter , prefix , and suffix .
*
* @ 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 & nbsp ; 16 ) .
* @ see java . util . HexFormat
* @ see # parseUnsignedInt ( String , int )
* @ see # toUnsignedString ( int , int )
* @ since 1 . 0 . 2
*/
public static String toHexString(int i) {
return toUnsignedString0(i, 4 );
}
/**
* Returns a string representation of the integer argument as an
* unsigned integer in base & nbsp ; 8 .
*
* < p > The unsigned integer value is the argument plus 2 < sup > 32 < / sup >
* if the argument is negative ; otherwise , it is equal to the
* argument . This value is converted to a string of ASCII digits
* in octal ( base & nbsp ; 8 ) with no extra leading { @ code 0 } s .
*
* < p > 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 ) } .
*
* < p > If the unsigned magnitude is zero , it is represented by a
* single zero character { @ code ' 0 ' } ( { @ code ' \ u005Cu0030 ' } ) ;
* 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 :
*
* < blockquote >
* { @ code 01234567 }
* < / blockquote >
*
* These are the characters { @ code ' \ u005Cu0030 ' } through
* { @ code ' \ u005Cu0037 ' } .
*
* @ 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 & nbsp ; 8 ) .
* @ see # parseUnsignedInt ( String , int )
* @ see # toUnsignedString ( int , int )
* @ since 1 . 0 . 2
*/
public static String toOctalString(int i) {
return toUnsignedString0(i, 3 );
}
/**
* Returns a string representation of the integer argument as an
* unsigned integer in base & nbsp ; 2 .
*
* < p > The unsigned integer value is the argument plus 2 < sup > 32 < / sup >
* 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 & nbsp ; 2 ) with no extra leading { @ code 0 } s .
*
* < p > 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 ) } .
*
* < p > If the unsigned magnitude is zero , it is represented by a
* single zero character { @ code ' 0 ' } ( { @ code ' \ u005Cu0030 ' } ) ;
* otherwise , the first character of the representation of the
* unsigned magnitude will not be the zero character . The
* characters { @ code ' 0 ' } ( { @ code ' \ u005Cu0030 ' } ) and { @ code
* ' 1 ' } ( { @ code ' \ u005Cu0031 ' } ) 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 & nbsp ; 2 ) .
* @ see # parseUnsignedInt ( String , int )
* @ see # toUnsignedString ( int , int )
* @ since 1 . 0 . 2
*/
public static String toBinaryString(int i) {
return toUnsignedString0(i, 1 );
}
/**
* Convert the integer to an unsigned number .
*/
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1 )) / shift), 1 );
if (COMPACT_STRINGS) {
byte [] buf = new byte [chars];
formatUnsignedInt(val, shift, buf, chars);
return new String(buf, LATIN1);
} else {
byte [] buf = new byte [chars * 2 ];
formatUnsignedIntUTF16(val, shift, buf, chars);
return new String(buf, UTF16);
}
}
/**
* Format an { @ code int } ( treated as unsigned ) into a byte buffer ( LATIN1 version ) . If
* { @ code len } exceeds the formatted ASCII representation of { @ code val } ,
* { @ code buf } will be padded with leading zeroes .
*
* @ param val the unsigned int to format
* @ param shift the log2 of the base to format in ( 4 for hex , 3 for octal , 1 for binary )
* @ param buf the byte buffer to write to
* @ param len the number of characters to write
*/
private static void formatUnsignedInt(int val, int shift, byte [] buf, int len) {
int charPos = len;
int radix = 1 << shift;
int mask = radix - 1 ;
do {
buf[--charPos] = (byte )Integer.digits[val & mask];
val >>>= shift;
} while (charPos > 0 );
}
/**
* Format an { @ code int } ( treated as unsigned ) into a byte buffer ( UTF16 version ) . If
* { @ code len } exceeds the formatted ASCII representation of { @ code val } ,
* { @ code buf } will be padded with leading zeroes .
*
* @ param val the unsigned int to format
* @ param shift the log2 of the base to format in ( 4 for hex , 3 for octal , 1 for binary )
* @ param buf the byte buffer to write to
* @ param len the number of characters to write
*/
private static void formatUnsignedIntUTF16(int val, int shift, byte [] buf, int len) {
int charPos = len;
int radix = 1 << shift;
int mask = radix - 1 ;
do {
StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
val >>>= shift;
} while (charPos > 0 );
}
static final byte [] DigitTens = {
'0' , '0' , '0' , '0' , '0' , '0' , '0' , '0' , '0' , '0' ,
'1' , '1' , '1' , '1' , '1' , '1' , '1' , '1' , '1' , '1' ,
'2' , '2' , '2' , '2' , '2' , '2' , '2' , '2' , '2' , '2' ,
'3' , '3' , '3' , '3' , '3' , '3' , '3' , '3' , '3' , '3' ,
'4' , '4' , '4' , '4' , '4' , '4' , '4' , '4' , '4' , '4' ,
'5' , '5' , '5' , '5' , '5' , '5' , '5' , '5' , '5' , '5' ,
'6' , '6' , '6' , '6' , '6' , '6' , '6' , '6' , '6' , '6' ,
'7' , '7' , '7' , '7' , '7' , '7' , '7' , '7' , '7' , '7' ,
'8' , '8' , '8' , '8' , '8' , '8' , '8' , '8' , '8' , '8' ,
'9' , '9' , '9' , '9' , '9' , '9' , '9' , '9' , '9' , '9' ,
} ;
static final byte [] DigitOnes = {
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
} ;
/**
* Returns a { @ code String } object representing the
* specified integer . The argument is converted to signed decimal
* representation and returned as a string , exactly as if the
* argument and radix 10 were given as arguments to the { @ link
* # toString ( int , int ) } method .
*
* @ param i an integer to be converted .
* @ return a string representation of the argument in base & nbsp ; 10 .
*/
@IntrinsicCandidate
public static String toString(int i) {
int size = stringSize(i);
if (COMPACT_STRINGS) {
byte [] buf = new byte [size];
getChars(i, size, buf);
return new String(buf, LATIN1);
} else {
byte [] buf = new byte [size * 2 ];
StringUTF16.getChars(i, size, buf);
return new String(buf, UTF16);
}
}
/**
* Returns a string representation of the argument as an unsigned
* decimal value .
*
* 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
* digit at the specified index ( exclusive ) , and working
* backwards from there .
*
* @ implNote This method converts positive inputs into negative
* values , to cover the Integer . MIN_VALUE case . Converting otherwise
* ( negative to positive ) will expose - Integer . MIN_VALUE that overflows
* integer .
*
* @ param i value to convert
* @ param index next index , after the least significant digit
* @ param buf target buffer , Latin1 - encoded
* @ return index of the most significant digit or minus sign , if present
*/
static int getChars(int i, int index, byte [] buf) {
int q, r;
int charPos = index;
boolean negative = i < 0 ;
if (!negative) {
i = -i;
}
// Generate two digits per iteration
while (i <= -100 ) {
q = i / 100 ;
r = (q * 100 ) - i;
i = q;
buf[--charPos] = DigitOnes[r];
buf[--charPos] = DigitTens[r];
}
// We know there are at most two digits left at this point.
buf[--charPos] = DigitOnes[-i];
if (i < -9 ) {
buf[--charPos] = DigitTens[-i];
}
if (negative) {
buf[--charPos] = (byte )'-' ;
}
return charPos;
}
// Left here for compatibility reasons, see JDK-8143900.
static final int [] sizeTable = { 9 , 99 , 999 , 9999 , 99999 , 999999 , 9999999 ,
99999999 , 999999999 , Integer.MAX_VALUE };
/**
* Returns the string representation size for a given int value .
*
* @ param x int value
* @ return string size
*
* @ implNote There are other ways to compute this : e . g . binary search ,
* but values are biased heavily towards zero , and therefore linear search
* wins . The iteration results are also routinely inlined in the generated
* code after loop unrolling .
*/
static int stringSize(int x) {
int d = 1 ;
if (x >= 0 ) {
d = 0 ;
x = -x;
}
int p = -10 ;
for (int i = 1 ; i < 10 ; i++) {
if (x > p)
return i + d;
p = 10 * p;
}
return 10 + d;
}
/**
* Parses the string argument as a signed 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 minus sign { @ code ' - ' } ( { @ code ' \ u005Cu002D ' } ) to
* indicate a negative value or an ASCII plus sign { @ code ' + ' }
* ( { @ code ' \ u005Cu002B ' } ) to indicate a positive value . The
* resulting integer value is returned .
*
* < p > An exception of type { @ code NumberFormatException } is
* thrown if any of the following situations occurs :
* < ul >
* < li > The first argument is { @ code null } or is a string of
* length zero .
*
* < li > The radix is either smaller than
* { @ link java . lang . Character # MIN_RADIX } or
* larger than { @ link java . lang . Character # MAX_RADIX } .
*
* < li > Any character of the string is not a digit of the specified
* radix , except that the first character may be a minus sign
* { @ code ' - ' } ( { @ code ' \ u005Cu002D ' } ) or plus sign
* { @ code ' + ' } ( { @ code ' \ u005Cu002B ' } ) provided that the
* string is longer than length 1 .
*
* < li > The value represented by the string is not a value of type
* { @ code int } .
* < / ul >
*
* < p > Examples :
* < blockquote > < pre >
* parseInt ( " 0 " , 10 ) returns 0
* parseInt ( " 473 " , 10 ) returns 473
* parseInt ( " + 42 " , 10 ) returns 42
* parseInt ( " - 0 " , 10 ) returns 0
* parseInt ( " - FF " , 16 ) returns - 255
* parseInt ( " 1100110 " , 2 ) returns 102
* parseInt ( " 2147483647 " , 10 ) returns 2147483647
* parseInt ( " - 2147483648 " , 10 ) returns - 2147483648
* parseInt ( " 2147483648 " , 10 ) throws a NumberFormatException
* parseInt ( " 99 " , 8 ) throws a NumberFormatException
* parseInt ( " Kona " , 10 ) throws a NumberFormatException
* parseInt ( " Kona " , 27 ) returns 411787
* < / pre > < / blockquote >
*
* @ param s the { @ code String } containing the 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 } .
*/
public static int parseInt(String s, int radix)
throws NumberFormatException
{
/*
* WARNING : This method may be invoked early during VM initialization
* before IntegerCache is initialized . Care must be taken to not use
* the valueOf method .
*/
if (s == null ) {
throw new NumberFormatException("Cannot parse null string" );
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX" );
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX" );
}
boolean negative = false ;
int i = 0 , len = s.length();
int limit = -Integer.MAX_VALUE;
if (len > 0 ) {
char firstChar = s.charAt(0 );
if (firstChar < '0' ) { // Possible leading "+" or "-"
if (firstChar == '-' ) {
negative = true ;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+' ) {
throw NumberFormatException.forInputString(s, radix);
}
if (len == 1 ) { // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s, radix);
}
i++;
}
int multmin = limit / radix;
int result = 0 ;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i++), radix);
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s, radix);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s, radix);
}
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s, radix);
}
}
/**
* Parses the { @ link CharSequence } argument as a signed { @ code int } in the
* specified { @ code radix } , beginning at the specified { @ code beginIndex }
* and extending to { @ code endIndex - 1 } .
*
* < p > The method does not take steps to guard against the
* { @ code CharSequence } being mutated while parsing .
*
* @ param s the { @ code CharSequence } containing the { @ code int }
* representation to be parsed
* @ param beginIndex the beginning index , inclusive .
* @ param endIndex the ending index , exclusive .
* @ param radix the radix to be used while parsing { @ code s } .
* @ return the signed { @ code int } represented by the subsequence in
* the specified radix .
* @ throws NullPointerException if { @ code s } is null .
* @ throws IndexOutOfBoundsException if { @ code beginIndex } is
* negative , or if { @ code beginIndex } is greater than
* { @ code endIndex } or if { @ code endIndex } is greater than
* { @ code s . length ( ) } .
* @ throws NumberFormatException if the { @ code CharSequence } does not
* contain a parsable { @ code int } in the specified
* { @ code radix } , or if { @ code radix } is either smaller than
* { @ link java . lang . Character # MIN_RADIX } or larger than
* { @ link java . lang . Character # MAX_RADIX } .
* @ since 9
*/
public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix)
throws NumberFormatException {
Objects.requireNonNull(s);
Objects.checkFromToIndex(beginIndex, endIndex, s.length());
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX" );
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX" );
}
boolean negative = false ;
int i = beginIndex;
int limit = -Integer.MAX_VALUE;
if (i < endIndex) {
char firstChar = s.charAt(i);
if (firstChar < '0' ) { // Possible leading "+" or "-"
if (firstChar == '-' ) {
negative = true ;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+') {
throw NumberFormatException.forCharSequence(s, beginIndex,
endIndex, i);
}
i++;
if (i == endIndex) { // Cannot have lone "+" or "-"
throw NumberFormatException.forCharSequence(s, beginIndex,
endIndex, i);
}
}
int multmin = limit / radix;
int result = 0 ;
while (i < endIndex) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i), radix);
if (digit < 0 || result < multmin) {
throw NumberFormatException.forCharSequence(s, beginIndex,
endIndex, i);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forCharSequence(s, beginIndex,
endIndex, i);
}
i++;
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString("" , radix);
}
}
/**
* Parses the string argument as a signed decimal integer . The
* characters in the string must all be decimal digits , except
* that the first character may be an ASCII minus sign { @ code ' - ' }
* ( { @ code ' \ u005Cu002D ' } ) to indicate a negative value or an
* ASCII plus sign { @ code ' + ' } ( { @ code ' \ u005Cu002B ' } ) to
* indicate a positive value . The resulting integer value is
* returned , exactly as if the argument and the radix 10 were
* given as arguments to the { @ link # parseInt ( java . lang . String ,
* int ) } method .
*
* @ param s a { @ code String } containing the { @ code int }
* representation to be parsed
* @ return the integer value represented by the argument in decimal .
* @ throws NumberFormatException if the string does not contain a
* parsable integer .
*/
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10 );
}
/**
* Parses the string argument as an unsigned integer in the radix
* specified by the second argument . An unsigned integer maps the
* values usually associated with negative numbers to positive
* numbers larger than { @ code MAX_VALUE } .
*
* 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 ' + ' } ( { @ code ' \ u005Cu002B ' } ) . The resulting
* integer value is returned .
*
* < p > An exception of type { @ code NumberFormatException } is
* thrown if any of the following situations occurs :
* < ul >
* < li > The first argument is { @ code null } or is a string of
* length zero .
*
* < li > The radix is either smaller than
* { @ link java . lang . Character # MIN_RADIX } or
* larger than { @ link java . lang . Character # MAX_RADIX } .
*
* < li > Any character of the string is not a digit of the specified
* radix , except that the first character may be a plus sign
* { @ code ' + ' } ( { @ code ' \ u005Cu002B ' } ) provided that the
* string is longer than length 1 .
*
* < li > The value represented by the string is larger than the
* largest unsigned { @ code int } , 2 < sup > 32 < / sup > - 1 .
*
* < / ul >
*
*
* @ 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("Cannot parse null string" );
}
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 & 0 xffff_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, radix);
}
}
/**
* Parses the { @ link CharSequence } argument as an unsigned { @ code int } in
* the specified { @ code radix } , beginning at the specified
* { @ code beginIndex } and extending to { @ code endIndex - 1 } .
*
* < p > The method does not take steps to guard against the
* { @ code CharSequence } being mutated while parsing .
*
* @ param s the { @ code CharSequence } containing the unsigned
* { @ code int } representation to be parsed
* @ param beginIndex the beginning index , inclusive .
* @ param endIndex the ending index , exclusive .
* @ param radix the radix to be used while parsing { @ code s } .
* @ return the unsigned { @ code int } represented by the subsequence in
* the specified radix .
* @ throws NullPointerException if { @ code s } is null .
* @ throws IndexOutOfBoundsException if { @ code beginIndex } is
* negative , or if { @ code beginIndex } is greater than
* { @ code endIndex } or if { @ code endIndex } is greater than
* { @ code s . length ( ) } .
* @ throws NumberFormatException if the { @ code CharSequence } does not
* contain a parsable unsigned { @ code int } in the specified
* { @ code radix } , or if { @ code radix } is either smaller than
* { @ link java . lang . Character # MIN_RADIX } or larger than
* { @ link java . lang . Character # MAX_RADIX } .
* @ since 9
*/
public static int parseUnsignedInt(CharSequence s, int beginIndex, int endIndex, int radix)
throws NumberFormatException {
Objects.requireNonNull(s);
Objects.checkFromToIndex(beginIndex, endIndex, s.length());
int start = beginIndex, len = endIndex - beginIndex;
if (len > 0 ) {
char firstChar = s.charAt(start);
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, start, start + len, radix);
} else {
long ell = Long .parseLong(s, start, start + len, radix);
if ((ell & 0 xffff_ffff_0000_0000L) == 0 ) {
return (int ) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int." , s));
}
}
}
} else {
throw new NumberFormatException("" );
}
}
/**
* 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 ASCII plus sign { @ code
* ' + ' } ( { @ code ' \ u005Cu002B ' } ) . 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
* is interpreted as representing a signed integer in the radix
* specified by the second argument , exactly as if the arguments
* were given to the { @ link # parseInt ( java . lang . String , int ) }
* method . The result is an { @ code Integer } object that
* represents the integer value specified by the string .
*
* < p > In other words , this method returns an { @ code Integer }
* object equal to the value of :
*
* < blockquote >
* { @ code Integer . valueOf ( Integer . parseInt ( s , radix ) ) }
* < / blockquote >
*
* @ param s the string to be parsed .
* @ param radix the radix to be used in interpreting { @ code s }
* @ return an { @ code Integer } object holding the value
* represented by the string argument in the specified
* radix .
* @ throws NumberFormatException if the { @ code String }
* does not contain a parsable { @ code int } .
*/
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
/**
* Returns an { @ code Integer } object holding the
* value of the specified { @ code String } . The argument is
* interpreted as representing a signed decimal integer , exactly
* as if the argument were given to the { @ link
* # parseInt ( java . lang . String ) } method . The result is an
* { @ code Integer } object that represents the integer value
* specified by the string .
*
* < p > In other words , this method returns an { @ code Integer }
* object equal to the value of :
*
* < blockquote >
* { @ code Integer . valueOf ( Integer . parseInt ( s ) ) }
* < / blockquote >
*
* @ param s the string to be parsed .
* @ return an { @ code Integer } object holding the value
* represented by the string argument .
* @ throws NumberFormatException if the string cannot be parsed
* as an integer .
*/
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10 ));
}
/**
* Cache to support the object identity semantics of autoboxing for values between
* - 128 and 127 ( inclusive ) as required by JLS .
*
* The cache is initialized on first usage . The size of the cache
* may be controlled by the { @ code - XX : AutoBoxCacheMax = < size > } option .
* During VM initialization , java . lang . Integer . IntegerCache . high property
* may be set and saved in the private system properties in the
* jdk . internal . misc . VM class .
*
* WARNING : The cache is archived with CDS and reloaded from the shared
* archive at runtime . The archived cache ( Integer [ ] ) and Integer objects
* reside in the closed archive heap regions . Care should be taken when
* changing the implementation and the cache array should not be assigned
* with new Integer object ( s ) after initialization .
*/
private static class IntegerCache {
static final int low = -128 ;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127 ;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high" );
if (integerCacheHighPropValue != null ) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127 );
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1 );
} catch ( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
CDS.initializeFromArchive(IntegerCache.class );
int size = (high - low) + 1 ;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for (int i = 0 ; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127 ;
}
private IntegerCache() {}
}
/**
* Returns an { @ code Integer } instance representing the specified
* { @ code int } value . If a new { @ code Integer } instance is not
* required , this method should generally be used in preference to
* the constructor { @ link # Integer ( int ) } , as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values .
*
* This method will always cache values in the range - 128 to 127 ,
* inclusive , and may cache other values outside of this range .
*
* @ param i an { @ code int } value .
* @ return an { @ code Integer } instance representing { @ code i } .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
/**
* The value of the { @ code Integer } .
*
* @ serial
*/
private final int value;
/**
* Constructs a newly allocated { @ code Integer } object that
* represents the specified { @ code int } value .
*
* @ param value the value to be represented by the
* { @ code Integer } object .
*
* @ deprecated
* It is rarely appropriate to use this constructor . The static factory
* { @ link # valueOf ( int ) } is generally a better choice , as it is
* likely to yield significantly better space and time performance .
*/
@Deprecated(since="9" , forRemoval = true )
public Integer(int value) {
this .value = value;
}
/**
* Constructs a newly allocated { @ code Integer } object that
* represents the { @ code int } value indicated by the
* { @ code String } parameter . The string is converted to an
* { @ code int } value in exactly the manner used by the
* { @ code parseInt } method for radix 10 .
*
* @ param s the { @ code String } to be converted to an { @ code Integer } .
* @ throws NumberFormatException if the { @ code String } does not
* contain a parsable integer .
*
* @ deprecated
* It is rarely appropriate to use this constructor .
* Use { @ link # parseInt ( String ) } to convert a string to a
* { @ code int } primitive , or use { @ link # valueOf ( String ) }
* to convert a string to an { @ code Integer } object .
*/
@Deprecated(since="9" , forRemoval = true )
public Integer(String s) throws NumberFormatException {
this .value = parseInt(s, 10 );
}
/**
* Returns the value of this { @ code Integer } as a { @ code byte }
* after a narrowing primitive conversion .
* @ jls 5 . 1 . 3 Narrowing Primitive Conversion
*/
public byte byteValue() {
return (byte )value;
}
/**
* Returns the value of this { @ code Integer } as a { @ code short }
* after a narrowing primitive conversion .
* @ jls 5 . 1 . 3 Narrowing Primitive Conversion
*/
public short shortValue() {
return (short )value;
}
/**
* Returns the value of this { @ code Integer } as an
* { @ code int } .
*/
@IntrinsicCandidate
public int intValue() {
return value;
}
/**
* Returns the value of this { @ code Integer } as a { @ code long }
* after a widening primitive conversion .
* @ jls 5 . 1 . 2 Widening Primitive Conversion
* @ see Integer # toUnsignedLong ( int )
*/
public long longValue() {
return (long )value;
}
/**
* Returns the value of this { @ code Integer } as a { @ code float }
* after a widening primitive conversion .
* @ jls 5 . 1 . 2 Widening Primitive Conversion
*/
public float floatValue() {
return (float )value;
}
/**
* Returns the value of this { @ code Integer } as a { @ code double }
* after a widening primitive conversion .
* @ jls 5 . 1 . 2 Widening Primitive Conversion
*/
public double doubleValue() {
return (double )value;
}
/**
* Returns a { @ code String } object representing this
* { @ code Integer } ' s value . The value is converted to signed
* decimal representation and returned as a string , exactly as if
* the integer value were given as an argument to the { @ link
* java . lang . Integer # toString ( int ) } method .
*
* @ return a string representation of the value of this object in
* base & nbsp ; 10 .
*/
public String toString() {
return toString(value);
}
/**
* Returns a hash code for this { @ code Integer } .
*
* @ return a hash code value for this object , equal to the
* primitive { @ code int } value represented by this
* { @ code Integer } object .
*/
@Override
public int hashCode() {
return Integer.hashCode(value);
}
/**
* Returns a hash code for an { @ code int } value ; compatible with
* { @ code Integer . hashCode ( ) } .
*
* @ param value the value to hash
* @ since 1 . 8
*
* @ return a hash code value for an { @ code int } value .
*/
public static int hashCode(int value) {
return value;
}
/**
* Compares this object to the specified object . The result is
* { @ code true } if and only if the argument is not
* { @ code null } and is an { @ code Integer } object that
* contains the same { @ code int } value as this object .
*
* @ param obj the object to compare with .
* @ return { @ code true } if the objects are the same ;
* { @ code false } otherwise .
*/
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false ;
}
/**
* Determines the integer value of the system property with the
* specified name .
*
* < p > The first argument is treated as the name of a system
* property . System properties are accessible through the { @ link
* java . lang . System # getProperty ( java . lang . String ) } method . The
* string value of this property is then interpreted as an integer
* value using the grammar supported by { @ link Integer # decode decode } and
* an { @ code Integer } object representing this value is returned .
*
* < p > If there is no property with the specified name , if the
* specified name is empty or { @ code null } , or if the property
* does not have the correct numeric format , then { @ code null } is
* returned .
*
* < p > In other words , this method returns an { @ code Integer }
* object equal to the value of :
*
* < blockquote >
* { @ code getInteger ( nm , null ) }
* < / blockquote >
*
* @ param nm property name .
* @ return the { @ code Integer } value of the property .
* @ throws SecurityException for the same reasons as
* { @ link System # getProperty ( String ) System . getProperty }
* @ see java . lang . System # getProperty ( java . lang . String )
* @ see java . lang . System # getProperty ( java . lang . String , java . lang . String )
*/
public static Integer getInteger(String nm) {
return getInteger(nm, null );
}
/**
* Determines the integer value of the system property with the
* specified name .
*
* < p > The first argument is treated as the name of a system
* property . System properties are accessible through the { @ link
* java . lang . System # getProperty ( java . lang . String ) } method . The
* string value of this property is then interpreted as an integer
* value using the grammar supported by { @ link Integer # decode decode } and
* an { @ code Integer } object representing this value is returned .
*
* < p > The second argument is the default value . An { @ code Integer } object
* that represents the value of the second argument is returned if there
* is no property of the specified name , if the property does not have
* the correct numeric format , or if the specified name is empty or
* { @ code null } .
*
* < p > In other words , this method returns an { @ code Integer } object
* equal to the value of :
*
* < blockquote >
* { @ code getInteger ( nm , Integer . valueOf ( val ) ) }
* < / blockquote >
*
* but in practice it may be implemented in a manner such as :
*
* < blockquote > < pre >
* Integer result = getInteger ( nm , null ) ;
* return ( result = = null ) ? Integer . valueOf ( val ) : result ;
* < / pre > < / blockquote >
*
* to avoid the unnecessary allocation of an { @ code Integer }
* object when the default value is not needed .
*
* @ param nm property name .
* @ param val default value .
* @ return the { @ code Integer } value of the property .
* @ throws SecurityException for the same reasons as
* { @ link System # getProperty ( String ) System . getProperty }
* @ see java . lang . System # getProperty ( java . lang . String )
* @ see java . lang . System # getProperty ( java . lang . String , java . lang . String )
*/
public static Integer getInteger(String nm, int val) {
Integer result = getInteger(nm, null );
return (result == null ) ? Integer.valueOf(val) : result;
}
/**
* Returns the integer value of the system property with the
* specified name . The first argument is treated as the name of a
* system property . System properties are accessible through the
* { @ link java . lang . System # getProperty ( java . lang . String ) } method .
* The string value of this property is then interpreted as an
* integer value , as per the { @ link Integer # decode decode } method ,
* and an { @ code Integer } object representing this value is
* returned ; in summary :
*
* < ul > < li > If the property value begins with the two ASCII characters
* { @ code 0 x } or the ASCII character { @ code # } , not
* followed by a minus sign , then the rest of it is parsed as a
* hexadecimal integer exactly as by the method
* { @ link # valueOf ( java . lang . String , int ) } with radix 16 .
* < li > If the property value begins with the ASCII character
* { @ code 0 } followed by another character , it is parsed as an
* octal integer exactly as by the method
* { @ link # valueOf ( java . lang . String , int ) } with radix 8 .
* < li > Otherwise , the property value is parsed as a decimal integer
* exactly as by the method { @ link # valueOf ( java . lang . String , int ) }
* with radix 10 .
* < / ul >
*
* < p > The second argument is the default value . The default value is
* returned if there is no property of the specified name , if the
* property does not have the correct numeric format , or if the
* specified name is empty or { @ code null } .
*
* @ param nm property name .
* @ param val default value .
* @ return the { @ code Integer } value of the property .
* @ throws SecurityException for the same reasons as
* { @ link System # getProperty ( String ) System . getProperty }
* @ see System # getProperty ( java . lang . String )
* @ see System # getProperty ( java . lang . String , java . lang . String )
*/
public static Integer getInteger(String nm, Integer val) {
String v = null ;
try {
v = System.getProperty(nm);
} catch (IllegalArgumentException | NullPointerException e) {
}
if (v != null ) {
try {
return Integer.decode(v);
} catch (NumberFormatException e) {
}
}
return val;
}
/**
* Decodes a { @ code String } into an { @ code Integer } .
* Accepts decimal , hexadecimal , and octal numbers given
* by the following grammar :
*
* < blockquote >
* < dl >
* < dt > < i > DecodableString : < / i >
* < dd > < i > Sign < sub > opt < / sub > DecimalNumeral < / i >
* < dd > < i > Sign < sub > opt < / sub > < / i > { @ code 0 x } < i > HexDigits < / i >
* < dd > < i > Sign < sub > opt < / sub > < / i > { @ code 0 X } < i > HexDigits < / i >
* < dd > < i > Sign < sub > opt < / sub > < / i > { @ code # } < i > HexDigits < / i >
* < dd > < i > Sign < sub > opt < / sub > < / i > { @ code 0 } < i > OctalDigits < / i >
*
* < dt > < i > Sign : < / i >
* < dd > { @ code - }
* < dd > { @ code + }
* < / dl >
* < / blockquote >
*
* < i > DecimalNumeral < / i > , < i > HexDigits < / i > , and < i > OctalDigits < / i >
* are as defined in section { @ jls 3 . 10 . 1 } of
* < cite > The Java Language Specification < / cite > ,
* except that underscores are not accepted between digits .
*
* < p > The sequence of characters following an optional
* sign and / or radix specifier ( " { @ code 0 x } " , " { @ code 0 X } " ,
* " { @ code # } " , or leading zero ) is parsed as by the { @ code
* Integer . parseInt } method with the indicated radix ( 10 , 16 , or
* 8 ) . This sequence of characters must represent a positive
* value or a { @ link NumberFormatException } will be thrown . The
* result is negated if first character of the specified { @ code
* String } is the minus sign . No whitespace characters are
* permitted in the { @ code String } .
*
* @ param nm the { @ code String } to decode .
* @ return an { @ code Integer } object holding the { @ code int }
* value represented by { @ code nm }
* @ throws NumberFormatException if the { @ code String } does not
* contain a parsable integer .
* @ see java . lang . Integer # parseInt ( java . lang . String , int )
*/
public static Integer decode(String nm) throws NumberFormatException {
int radix = 10 ;
int index = 0 ;
boolean negative = false ;
int result;
if (nm.isEmpty())
throw new NumberFormatException("Zero length string" );
char firstChar = nm.charAt(0 );
// Handle sign, if present
if (firstChar == '-' ) {
negative = true ;
index++;
} else if (firstChar == '+' )
index++;
// Handle radix specifier, if present
if (nm.startsWith("0x" , index) || nm.startsWith("0X" , index)) {
index += 2 ;
radix = 16 ;
}
else if (nm.startsWith("#" , index)) {
index ++;
radix = 16 ;
}
else if (nm.startsWith("0" , index) && nm.length() > 1 + index) {
index ++;
radix = 8 ;
}
if (nm.startsWith("-" , index) || nm.startsWith("+" , index))
throw new NumberFormatException("Sign character in wrong position" );
try {
result = parseInt(nm, index, nm.length(), radix);
result = negative ? -result : result;
} catch (NumberFormatException e) {
// If number is Integer.MIN_VALUE, we'll end up here. The next line
// handles this case, and causes any genuine format error to be
// rethrown.
String constant = negative ? ("-" + nm.substring(index))
: nm.substring(index);
result = parseInt(constant, radix);
}
return result;
}
/**
* Compares two { @ code Integer } objects numerically .
*
* @ param anotherInteger the { @ code Integer } to be compared .
* @ return the value { @ code 0 } if this { @ code Integer } is
* equal to the argument { @ code Integer } ; a value less than
* { @ code 0 } if this { @ code Integer } is numerically less
* than the argument { @ code Integer } ; and a value greater
* than { @ code 0 } if this { @ code Integer } is numerically
* greater than the argument { @ code Integer } ( signed
* comparison ) .
* @ since 1 . 2
*/
public int compareTo(Integer anotherInteger) {
return compare(this .value, anotherInteger.value);
}
/**
* Compares two { @ code int } values numerically .
* The value returned is identical to what would be returned by :
* < pre >
* Integer . valueOf ( x ) . compareTo ( Integer . valueOf ( y ) )
* < / pre >
*
* @ 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 } ; and
* a value greater than { @ code 0 } if { @ code x > y }
* @ since 1 . 7
*/
public static int compare(int x, int y) {
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
*/
@IntrinsicCandidate
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 .
*
* Consequently , zero and positive { @ code int } values are mapped
* to a numerically equal { @ code long } value and negative { @ code
* int } values are mapped to a { @ code long } value equal to the
* input plus 2 < sup > 32 < / sup > .
*
* @ param x the value to convert to an unsigned { @ code long }
* @ return the argument converted to { @ code long } by an unsigned
* conversion
* @ since 1 . 8
*/
public static long toUnsignedLong(int x) {
return ((long ) x) & 0 xffffffffL;
}
/**
* Returns the unsigned quotient of dividing the first argument by
* the second where each argument and the result is interpreted as
* an unsigned value .
*
* < p > Note that in two ' s complement arithmetic , the three other
* basic arithmetic operations of add , subtract , and multiply are
* bit - wise identical if the two operands are regarded as both
* being signed or both being unsigned . Therefore separate { @ code
* addUnsigned } , etc . methods are not provided .
*
* @ param dividend the value to be divided
* @ param divisor the value doing the dividing
* @ return the unsigned quotient of the first argument divided by
* the second argument
* @ see # remainderUnsigned
* @ since 1 . 8
*/
@IntrinsicCandidate
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 and the result is interpreted
* as an unsigned value .
*
* @ param dividend the value to be divided
* @ param divisor the value doing the dividing
* @ return the unsigned remainder of the first argument divided by
* the second argument
* @ see # divideUnsigned
* @ since 1 . 8
*/
@IntrinsicCandidate
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
/**
* The number of bits used to represent an { @ code int } value in two ' s
* complement binary form .
*
* @ since 1 . 5
*/
@Native public static final int SIZE = 32 ;
/**
* The number of bytes used to represent an { @ code int } value in two ' s
* complement binary form .
*
* @ since 1 . 8
*/
public static final int BYTES = SIZE / Byte .SIZE;
/**
* Returns an { @ code int } value with at most a single one - bit , in the
* position of the highest - order ( " leftmost " ) one - bit in the specified
* { @ code int } value . Returns zero if the specified value has no
* one - bits in its two ' s complement binary representation , that is , if it
* is equal to zero .
*
* @ param i the value whose highest one bit is to be computed
* @ return an { @ code int } value with a single one - bit , in the position
* of the highest - order one - bit in the specified value , or zero if
* the specified value is itself equal to zero .
* @ since 1 . 5
*/
public static int highestOneBit(int i) {
return i & (MIN_VALUE >>> numberOfLeadingZeros(i));
}
/**
* Returns an { @ code int } value with at most a single one - bit , in the
* position of the lowest - order ( " rightmost " ) one - bit in the specified
* { @ code int } value . Returns zero if the specified value has no
* one - bits in its two ' s complement binary representation , that is , if it
* is equal to zero .
*
* @ param i the value whose lowest one bit is to be computed
* @ return an { @ code int } value with a single one - bit , in the position
* of the lowest - order one - bit in the specified value , or zero if
* the specified value is itself equal to zero .
* @ since 1 . 5
*/
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
/**
* Returns the number of zero bits preceding the highest - order
* ( " leftmost " ) one - bit in the two ' s complement binary representation
* of the specified { @ code int } value . Returns 32 if the
* specified value has no one - bits in its two ' s complement representation ,
* in other words if it is equal to zero .
*
* < p > Note that this method is closely related to the logarithm base 2 .
* For all positive { @ code int } values x :
* < ul >
* < li > floor ( log < sub > 2 < / sub > ( x ) ) = { @ code 31 - numberOfLeadingZeros ( x ) }
* < li > ceil ( log < sub > 2 < / sub > ( x ) ) = { @ code 32 - numberOfLeadingZeros ( x - 1 ) }
* < / ul >
*
* @ param i the value whose number of leading zeros is to be computed
* @ return the number of zero bits preceding the highest - order
* ( " leftmost " ) one - bit in the two ' s complement binary representation
* of the specified { @ code int } value , or 32 if the value
* is equal to zero .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static int numberOfLeadingZeros(int i) {
// HD, Count leading 0's
if (i <= 0 )
return i == 0 ? 32 : 0 ;
int n = 31 ;
if (i >= 1 << 16 ) { n -= 16 ; i >>>= 16 ; }
if (i >= 1 << 8 ) { n -= 8 ; i >>>= 8 ; }
if (i >= 1 << 4 ) { n -= 4 ; i >>>= 4 ; }
if (i >= 1 << 2 ) { n -= 2 ; i >>>= 2 ; }
return n - (i >>> 1 );
}
/**
* Returns the number of zero bits following the lowest - order ( " rightmost " )
* one - bit in the two ' s complement binary representation of the specified
* { @ code int } value . Returns 32 if the specified value has no
* one - bits in its two ' s complement representation , in other words if it is
* equal to zero .
*
* @ param i the value whose number of trailing zeros is to be computed
* @ return the number of zero bits following the lowest - order ( " rightmost " )
* one - bit in the two ' s complement binary representation of the
* specified { @ code int } value , or 32 if the value is equal
* to zero .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static int numberOfTrailingZeros(int i) {
// HD, Count trailing 0's
i = ~i & (i - 1 );
if (i <= 0 ) return i & 32 ;
int n = 1 ;
if (i > 1 << 16 ) { n += 16 ; i >>>= 16 ; }
if (i > 1 << 8 ) { n += 8 ; i >>>= 8 ; }
if (i > 1 << 4 ) { n += 4 ; i >>>= 4 ; }
if (i > 1 << 2 ) { n += 2 ; i >>>= 2 ; }
return n + (i >>> 1 );
}
/**
* Returns the number of one - bits in the two ' s complement binary
* representation of the specified { @ code int } value . This function is
* sometimes referred to as the < i > population count < / i > .
*
* @ param i the value whose bits are to be counted
* @ return the number of one - bits in the two ' s complement binary
* representation of the specified { @ code int } value .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1 ) & 0 x55555555);
i = (i & 0 x33333333) + ((i >>> 2 ) & 0 x33333333);
i = (i + (i >>> 4 )) & 0 x0f0f0f0f;
i = i + (i >>> 8 );
i = i + (i >>> 16 );
return i & 0 x3f;
}
/**
* Returns the value obtained by rotating the two ' s complement binary
* representation of the specified { @ code int } value left by the
* specified number of bits . ( Bits shifted out of the left hand , or
* high - order , side reenter on the right , or low - order . )
*
* < p > Note that left rotation with a negative distance is equivalent to
* right rotation : { @ code rotateLeft ( val , - distance ) = = rotateRight ( val ,
* distance ) } . Note also that rotation by any multiple of 32 is a
* no - op , so all but the last five bits of the rotation distance can be
* ignored , even if the distance is negative : { @ code rotateLeft ( val ,
* distance ) = = rotateLeft ( val , distance & 0 x1F ) } .
*
* @ param i the value whose bits are to be rotated left
* @ param distance the number of bit positions to rotate left
* @ return the value obtained by rotating the two ' s complement binary
* representation of the specified { @ code int } value left by the
* specified number of bits .
* @ since 1 . 5
*/
public static int rotateLeft(int i, int distance) {
return (i << distance) | (i >>> -distance);
}
/**
* Returns the value obtained by rotating the two ' s complement binary
* representation of the specified { @ code int } value right by the
* specified number of bits . ( Bits shifted out of the right hand , or
* low - order , side reenter on the left , or high - order . )
*
* < p > Note that right rotation with a negative distance is equivalent to
* left rotation : { @ code rotateRight ( val , - distance ) = = rotateLeft ( val ,
* distance ) } . Note also that rotation by any multiple of 32 is a
* no - op , so all but the last five bits of the rotation distance can be
* ignored , even if the distance is negative : { @ code rotateRight ( val ,
* distance ) = = rotateRight ( val , distance & 0 x1F ) } .
*
* @ param i the value whose bits are to be rotated right
* @ param distance the number of bit positions to rotate right
* @ return the value obtained by rotating the two ' s complement binary
* representation of the specified { @ code int } value right by the
* specified number of bits .
* @ since 1 . 5
*/
public static int rotateRight(int i, int distance) {
return (i >>> distance) | (i << -distance);
}
/**
* Returns the value obtained by reversing the order of the bits in the
* two ' s complement binary representation of the specified { @ code int }
* value .
*
* @ param i the value to be reversed
* @ return the value obtained by reversing order of the bits in the
* specified { @ code int } value .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0 x55555555) << 1 | (i >>> 1 ) & 0 x55555555;
i = (i & 0 x33333333) << 2 | (i >>> 2 ) & 0 x33333333;
i = (i & 0 x0f0f0f0f) << 4 | (i >>> 4 ) & 0 x0f0f0f0f;
return reverseBytes(i);
}
/**
* Returns the value obtained by compressing the bits of the
* specified { @ code int } value , { @ code i } , in accordance with
* the specified bit mask .
* < p >
* For each one - bit value { @ code mb } of the mask , from least
* significant to most significant , the bit value of { @ code i } at
* the same bit location as { @ code mb } is assigned to the compressed
* value contiguously starting from the least significant bit location .
* All the upper remaining bits of the compressed value are set
* to zero .
*
* @ apiNote
* Consider the simple case of compressing the digits of a hexadecimal
* value :
* { @ snippet lang = " java " :
* // Compressing drink to food
* compress ( 0 xCAFEBABE , 0 xFF00FFF0 ) = = 0 xCABAB
* }
* Starting from the least significant hexadecimal digit at position 0
* from the right , the mask { @ code 0 xFF00FFF0 } selects hexadecimal digits
* at positions 1 , 2 , 3 , 6 and 7 of { @ code 0 xCAFEBABE } . The selected digits
* occur in the resulting compressed value contiguously from digit position
* 0 in the same order .
* < p >
* The following identities all return { @ code true } and are helpful to
* understand the behaviour of { @ code compress } :
* { @ snippet lang = " java " :
* // Returns 1 if the bit at position n is one
* compress ( x , 1 < < n ) = = ( x > > n & 1 )
*
* // Logical shift right
* compress ( x , - 1 < < n ) = = x > > > n
*
* // Any bits not covered by the mask are ignored
* compress ( x , m ) = = compress ( x & m , m )
*
* // Compressing a value by itself
* compress ( m , m ) = = ( m = = - 1 | | m = = 0 ) ? m : ( 1 < < bitCount ( m ) ) - 1
*
* // Expanding then compressing with the same mask
* compress ( expand ( x , m ) , m ) = = x & compress ( m , m )
* }
* < p >
* The Sheep And Goats ( SAG ) operation ( see Hacker ' s Delight , section 7 . 7 )
* can be implemented as follows :
* { @ snippet lang = " java " :
* int compressLeft ( int i , int mask ) {
* // This implementation follows the description in Hacker's Delight which
* // is informative. A more optimal implementation is:
* // Integer.compress(i, mask) << -Integer.bitCount(mask)
* return Integer . reverse (
* Integer . compress ( Integer . reverse ( i ) , Integer . reverse ( mask ) ) ) ;
* }
*
* int sag ( int i , int mask ) {
* return compressLeft ( i , mask ) | Integer . compress ( i , ~ mask ) ;
* }
*
* // Separate the sheep from the goats
* sag ( 0 xCAFEBABE , 0 xFF00FFF0 ) = = 0 xCABABFEE
* }
*
* @ param i the value whose bits are to be compressed
* @ param mask the bit mask
* @ return the compressed value
* @ see # expand
* @ since 19
*/
@IntrinsicCandidate
public static int compress(int i, int mask) {
// See Hacker's Delight (2nd ed) section 7.4 Compress, or Generalized Extract
i = i & mask; // Clear irrelevant bits
int maskCount = ~mask << 1 ; // Count 0's to right
for (int j = 0 ; j < 5 ; j++) {
// Parallel prefix
// Mask prefix identifies bits of the mask that have an odd number of 0's to the right
int maskPrefix = parallelSuffix(maskCount);
// Bits to move
int maskMove = maskPrefix & mask;
// Compress mask
mask = (mask ^ maskMove) | (maskMove >>> (1 << j));
// Bits of i to be moved
int t = i & maskMove;
// Compress i
i = (i ^ t) | (t >>> (1 << j));
// Adjust the mask count by identifying bits that have 0 to the right
maskCount = maskCount & ~maskPrefix;
}
return i;
}
/**
* Returns the value obtained by expanding the bits of the
* specified { @ code int } value , { @ code i } , in accordance with
* the specified bit mask .
* < p >
* For each one - bit value { @ code mb } of the mask , from least
* significant to most significant , the next contiguous bit value
* of { @ code i } starting at the least significant bit is assigned
* to the expanded value at the same bit location as { @ code mb } .
* All other remaining bits of the expanded value are set to zero .
*
* @ apiNote
* Consider the simple case of expanding the digits of a hexadecimal
* value :
* { @ snippet lang = " java " :
* expand ( 0 x0000CABAB , 0 xFF00FFF0 ) = = 0 xCA00BAB0
* }
* Starting from the least significant hexadecimal digit at position 0
* from the right , the mask { @ code 0 xFF00FFF0 } selects the first five
* hexadecimal digits of { @ code 0 x0000CABAB } . The selected digits occur
* in the resulting expanded value in order at positions 1 , 2 , 3 , 6 , and 7 .
* < p >
* The following identities all return { @ code true } and are helpful to
* understand the behaviour of { @ code expand } :
* { @ snippet lang = " java " :
* // Logically shift right the bit at position 0
* expand ( x , 1 < < n ) = = ( x & 1 ) < < n
*
* // Logically shift right
* expand ( x , - 1 < < n ) = = x < < n
*
* // Expanding all bits returns the mask
* expand ( - 1 , m ) = = m
*
* // Any bits not covered by the mask are ignored
* expand ( x , m ) = = expand ( x , m ) & m
*
* // Compressing then expanding with the same mask
* expand ( compress ( x , m ) , m ) = = x & m
* }
* < p >
* The select operation for determining the position of the one - bit with
* index { @ code n } in a { @ code int } value can be implemented as follows :
* { @ snippet lang = " java " :
* int select ( int i , int n ) {
* // the one-bit in i (the mask) with index n
* int nthBit = Integer . expand ( 1 < < n , i ) ;
* // the bit position of the one-bit with index n
* return Integer . numberOfTrailingZeros ( nthBit ) ;
* }
*
* // The one-bit with index 0 is at bit position 1
* select ( 0 b10101010_10101010 , 0 ) = = 1
* // The one-bit with index 3 is at bit position 7
* select ( 0 b10101010_10101010 , 3 ) = = 7
* }
*
* @ param i the value whose bits are to be expanded
* @ param mask the bit mask
* @ return the expanded value
* @ see # compress
* @ since 19
* /
@ IntrinsicCandidate
public static int expand ( int i , int mask ) {
// Save original mask
int originalMask = mask ;
// Count 0's to right
int maskCount = ~ mask < < 1 ;
int maskPrefix = parallelSuffix ( maskCount ) ;
// Bits to move
int maskMove1 = maskPrefix & mask ;
// Compress mask
mask = ( mask ^ maskMove1 ) | ( maskMove1 > > > ( 1 < < 0 ) ) ;
maskCount = maskCount & ~ maskPrefix ;
maskPrefix = parallelSuffix ( maskCount ) ;
// Bits to move
int maskMove2 = maskPrefix & mask ;
// Compress mask
mask = ( mask ^ maskMove2 ) | ( maskMove2 > > > ( 1 < < 1 ) ) ;
maskCount = maskCount & ~ maskPrefix ;
maskPrefix = parallelSuffix ( maskCount ) ;
// Bits to move
int maskMove3 = maskPrefix & mask ;
// Compress mask
mask = ( mask ^ maskMove3 ) | ( maskMove3 > > > ( 1 < < 2 ) ) ;
maskCount = maskCount & ~ maskPrefix ;
maskPrefix = parallelSuffix ( maskCount ) ;
// Bits to move
int maskMove4 = maskPrefix & mask ;
// Compress mask
mask = ( mask ^ maskMove4 ) | ( maskMove4 > > > ( 1 < < 3 ) ) ;
maskCount = maskCount & ~ maskPrefix ;
maskPrefix = parallelSuffix ( maskCount ) ;
// Bits to move
int maskMove5 = maskPrefix & mask ;
int t = i < < ( 1 < < 4 ) ;
i = ( i & ~ maskMove5 ) | ( t & maskMove5 ) ;
t = i < < ( 1 < < 3 ) ;
i = ( i & ~ maskMove4 ) | ( t & maskMove4 ) ;
t = i < < ( 1 < < 2 ) ;
i = ( i & ~ maskMove3 ) | ( t & maskMove3 ) ;
t = i < < ( 1 < < 1 ) ;
i = ( i & ~ maskMove2 ) | ( t & maskMove2 ) ;
t = i < < ( 1 < < 0 ) ;
i = ( i & ~ maskMove1 ) | ( t & maskMove1 ) ;
// Clear irrelevant bits
return i & originalMask ;
}
@ ForceInline
private static int parallelSuffix ( int maskCount ) {
int maskPrefix = maskCount ^ ( maskCount < < 1 ) ;
maskPrefix = maskPrefix ^ ( maskPrefix < < 2 ) ;
maskPrefix = maskPrefix ^ ( maskPrefix < < 4 ) ;
maskPrefix = maskPrefix ^ ( maskPrefix < < 8 ) ;
maskPrefix = maskPrefix ^ ( maskPrefix < < 16 ) ;
return maskPrefix ;
}
/**
* Returns the signum function of the specified { @ code int } value . ( The
* return value is - 1 if the specified value is negative ; 0 if the
* specified value is zero ; and 1 if the specified value is positive . )
*
* @ param i the value whose signum is to be computed
* @ return the signum function of the specified { @ code int } value .
* @ since 1 . 5
*/
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31 ) | (-i >>> 31 );
}
/**
* Returns the value obtained by reversing the order of the bytes in the
* two ' s complement representation of the specified { @ code int } value .
*
* @ param i the value whose bytes are to be reversed
* @ return the value obtained by reversing the bytes in the specified
* { @ code int } value .
* @ since 1 . 5
*/
@IntrinsicCandidate
public static int reverseBytes(int i) {
return (i << 24 ) |
((i & 0 xff00) << 8 ) |
((i >>> 8 ) & 0 xff00) |
(i >>> 24 );
}
/**
* Adds two integers together as per the + operator .
*
* @ param a the first operand
* @ param b the second operand
* @ return the sum of { @ code a } and { @ code b }
* @ see java . util . function . BinaryOperator
* @ since 1 . 8
*/
public static int sum(int a, int b) {
return a + b;
}
/**
* Returns the greater of two { @ code int } values
* as if by calling { @ link Math # max ( int , int ) Math . max } .
*
* @ param a the first operand
* @ param b the second operand
* @ return the greater of { @ code a } and { @ code b }
* @ see java . util . function . BinaryOperator
* @ since 1 . 8
*/
public static int max(int a, int b) {
return Math.max(a, b);
}
/**
* Returns the smaller of two { @ code int } values
* as if by calling { @ link Math # min ( int , int ) Math . min } .
*
* @ param a the first operand
* @ param b the second operand
* @ return the smaller of { @ code a } and { @ code b }
* @ see java . util . function . BinaryOperator
* @ since 1 . 8
*/
public static int min(int a, int b) {
return Math.min(a, b);
}
/**
* Returns an { @ link Optional } containing the nominal descriptor for this
* instance , which is the instance itself .
*
* @ return an { @ link Optional } describing the { @ linkplain Integer } instance
* @ since 12
*/
@Override
public Optional<Integer> describeConstable() {
return Optional.of(this );
}
/**
* Resolves this instance as a { @ link ConstantDesc } , the result of which is
* the instance itself .
*
* @ param lookup ignored
* @ return the { @ linkplain Integer } instance
* @ since 12
*/
@Override
public Integer resolveConstantDesc(MethodHandles.Lookup lookup) {
return this ;
}
/** use serialVersionUID from JDK 1.0.2 for interoperability */
@java.io.Serial
@Native private static final long serialVersionUID = 1360826667806852920 L;
}
Messung V0.5 in Prozent C=94 H=92 G=92
¤ Dauer der Verarbeitung: 0.257 Sekunden
¤
*© Formatika GbR, Deutschland