United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4215269 : Some Integer.toHexString(int) results cannot be decoded back to an int

Details
Type:
Enhancement
Submit Date:
1999-02-26
Status:
Closed
Updated Date:
2012-05-07
Project Name:
JDK
Resolved Date:
2012-05-07
Component:
core-libs
OS:
generic,linux,solaris_8,solaris_10,windows_98,windows_2000,windows_vista,windows_7
Sub-Component:
java.lang
CPU:
generic,x86,sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
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
Fixed Versions:

Related Reports
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Relates:

Sub Tasks

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
PUBLIC COMMENTS

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

See 4504839.
                                     
2012-01-21
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)
======================================================================
                                     
2004-09-05
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang


                                     
2004-09-05
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
                                     
1999-05-03



Hardware and Software, Engineered to Work Together