JDK-8236406 : Minus sign issues for hex octal and binary literals
  • Type: Bug
  • Component: core-libs
  • Affected Version: 13
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: x86
  • Submitted: 2019-12-19
  • Updated: 2020-01-02
  • Resolved: 2020-01-02
Description
ADDITIONAL SYSTEM INFORMATION :
openjdk version "13" 2019-09-17
OpenJDK Runtime Environment (build 13+33-Ubuntu-1)


A DESCRIPTION OF THE PROBLEM :
I noticed that Integers (or probably also other data types) can be assigned with unsigned hex, octal or binary literals, but it is still possible to add a minus sign. I think this is not defined in the language specification and there are two issues that can occur:
1. If a minus sign is applied to an already negative literal, there is an implicit double negation, which can be really confusing.
2. Negating the most negative number should not be allowed since it would produce 2,147,483,648, which is bigger than the maximum positive Integer. However, in this case the negation just does nothing or I assume an overflow occurs that produces the same number.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
int a =  0x8000_0001; 
System.out.println("a: "+a); // -2,147,483,647 
int b = -0x8000_0001; // this implicit double negation produces the positive value 0x7FFF_FFFF
System.out.println("b: "+b ); // 2,147,483,647

int c =  0x8000_0000; 
System.out.println("c: "+c); // -2,147,483,648
int d = -0x8000_0000; //Negating the most negative integer should not be allowed, but it just does nothing.
System.out.println("d: "+d); // -2,147,483,648


FREQUENCY : always



Comments
The language spec does cover the cases in question here. First, the text to integer conversion is discussed in 3.10.1. Integer Literals (https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10). The minus sign is *not* considered part of the textual value being converted; there is a special check to allow "-2147483648" as valid input. Once an integer value is being operated on by a unary minus, the rules of 15.15.4. Unary Minus Operator - (https://docs.oracle.com/javase/specs/jls/se13/html/jls-15.html#jls-15.15.4) are in play: "For integer values, negation is the same as subtraction from zero. The Java programming language uses two's-complement representation for integers, and the range of two's-complement values is not symmetric, so negation of the maximum negative int or long results in that same maximum negative number. Overflow occurs in this case, but no exception is thrown. For all integer values x, -x equals (~x)+1. " While the behavior in question may be surprising, it is documented an following the spec. Closing as not a bug.
02-01-2020

Assigning to Joe for now ( maybe there is some prior history here? ). Please reassign as appropriate.
20-12-2019