JDK-4215269 : Some Integer.toHexString(int) results cannot be decoded back to an int
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version:
    1.1.7,1.2.0,1.2.1,1.2.2,1.4.0,1.4.1,1.4.2,6u2,6u22,6u26,7 1.1.7,1.2.0,1.2.1,1.2.2,1.4.0,1.4.1,1.4.2,6u2,6u22,6u26,7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,linux,solaris_8,solaris_10,windows_98,windows_2000,windows_vista,windows_7 generic,linux,solaris_8,solaris_10,windows_98,windows_2000,windows_vista,windows_7
  • CPU: generic,x86,sparc
  • Submitted: 1999-02-26
  • Updated: 2012-05-07
  • Resolved: 2012-05-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b25Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
Name: dbT83986			Date: 02/25/99


If you pass a negative number to Integer.toHexString(int) and feed the result
into a Integer.parseInt(String) or a Integer.decode(String), a NumberFormatException
is thrown.  Theoretically, if the string is built using a java.lang API, then it should be
decoded.

What is probably happening is the Integer.parseInt(String) and related APIs are
assuming a signed integer value and the Integer.toHexString(int) and related
functions use the actual bits of the value to render a string thus making it
unsigned.  The string encoder APIs then produce a number that is out of the
signed Integer's range.

The same problem occurs when using Integer.toBinaryString(int) and
Integer.toOctalString(int).

Because these values are not properly encoded/decoded, perhaps these
APIs should be deprecated or handling put in place to apply a sign to the
hexadecimal/octal/binary string before throwing an exception.


ParseTest.java:

class ParseTest {
        public static void main(String args[]){

                int test = Integer.parseInt(Integer.toHexString(1), 16);
                System.out.println("Successfully encoded/decoded " + test);

                test = Integer.parseInt(Integer.toHexString(-1), 16);
                        //      throws NumberFormatException
                System.out.println("Successfully encoded/decoded " + test);
        }
}

bash-2.01$ /usr/java/bin/javac ParseTest.java
bash-2.01$ /usr/java/bin/java ParseTest
Successfully encoded/decoded 1
Exception in thread "main" java.lang.NumberFormatException: ffffffff
        at java.lang.Integer.parseInt(Compiled Code)
        at ParseTest.main(ParseTest.java:7)
bash-2.01$
(Review ID: 48680)
======================================================================

Name: skT88420			Date: 07/27/99


I cannot get a java.lang.Long with parseLong() or valueOf() from
a string I've produced from a negative Long using toHexString()
(I expect the same applies to similar functions). It throws a
java.lang.NumberFormatException.

See bug #4215269 which lists the same issue for java.lang.Integer.
Either please genericize that bug to include Long and any other 
types to which it may apply or regard this as a seperate bug
request. I really think this should be a bug not an RFE.
It seems to apply to all versions of java. I tried 1.1.8 as 
well as 1.2.2.
(Review ID: 93117)
======================================================================

Name: krT82822			Date: 08/12/99


String s = "";
        int n;
        for(int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++)
        {
            try
            {
                s = Integer.toHexString(i);
                n = Integer.parseInt(s, 16);
            }
            catch(Exception e)
            {
                System.out.println("failed on " + s + "("+i+")");
                break;
            }
        }
(Review ID: 93802)
======================================================================

Name: skT88420			Date: 09/30/99


The output of Long.toBinaryString cannot be parsed by
parseLong(str,2) for negative numbers. In general
Long.toXXXString called on negative numbers produces
output that will not be accepted by parseLong(str,x).

This is because the parseLong requires that negative numbers be
prefixed by a "-" sign, and toXXXString only uses prepends
a "-" sign for decimal notation.

example code:

public class T {
  public static void main(String[] args) {
    long i = -1L;
    String str = "";
    try {
      
      System.err.println("long "+i);

      str = Long.toString(i);
      System.err.println(str);
      System.err.println(Long.parseLong(str));
      System.err.println("");

      str = Long.toBinaryString(i);
      System.err.println(str);
      System.err.println(Long.parseLong(str,2));
      System.err.println("");
      str = Long.toOctalString(i);
      System.err.println(str);
      System.err.println(Long.parseLong(str,8));
      System.err.println("");


      str = Long.toHexString(i);
      System.err.println(str);
      System.err.println(Long.parseLong(str,16));
      System.err.println("");

    } catch (NumberFormatException e) {
      e.printStackTrace();
    }
  }
}

Produces the following output:

vega.ccs.neu.edu(56): CLASSPATH= java T
long -1
-1
-1

1111111111111111111111111111111111111111111111111111111111111111
java.lang.NumberFormatException: 1111111111111111111111111111111111111111111111111111111111111111
	at java.lang.Throwable.fillInStackTrace(Native Method)
	at java.lang.Throwable.<init>(Throwable.java:94)
	at java.lang.Exception.<init>(Exception.java:42)
	at java.lang.RuntimeException.<init>(RuntimeException.java:47)
	at java.lang.IllegalArgumentException.<init>(IllegalArgumentException.java:43)
	at java.lang.NumberFormatException.<init>(NumberFormatException.java:43)
	at java.lang.Long.parseLong(Compiled Code)
	at T.main(T.java:16)

vega.ccs.neu.edu(57): java -version
java version "1.2"
Solaris VM (build Solaris_JDK_1.2_01, native threads, sunwjit)

vega.ccs.neu.edu(58): java -fullversion
java full version "Solaris_JDK_1.2_01"
(Review ID: 95986)
======================================================================
###@###.### 10/28/04 01:03 GMT

Comments
SUGGESTED FIX See 4504839.
21-01-2012

PUBLIC COMMENTS See http://hg.openjdk.java.net/jdk8/tl/jdk/rev/71200c517524
21-01-2012

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang
05-09-2004

WORK AROUND Name: dbT83986 Date: 02/25/99 Don't use the to*String(int) functions and expect to convert them back if you're dealing with possibly negative numbers. Use Integer.toString(int, int radix). You will get a '-' sign in front of the negative number which may be ugly, but it works. Another solution is to use a Long as in this example: int test; long temp; temp = Long.parseLong(Integer.toHexString(-1), 16); if(temp >= 2^32) temp -= 2^32; test = (int)temp; It's more code, but it works. This handling should really go in the string decoder APIs though. ====================================================================== Name: skT88420 Date: 07/27/99 I need to convert the string the hard way. I assume at some performance cost. (Review ID: 93117) ======================================================================
05-09-2004

EVALUATION I changed this to an RFE. The user does not claim that the current behavior is non-conformant to the spec, though it violates what he feels is an important invariant. william.maddox@Eng 1999-05-03 Methods to read unsigned text representations of integers should be added. ###@###.### 2001-09-19 Unsigned library work not likely for Tiger. ###@###.### 2003-09-30
03-05-1999