The unary minus operator is used to negate a numeric value, (and
sometimes to promote the value's type to int
in the
process).
Unary Minus operators can be used in unary minus expressions. Unary minus expressions can be expressed through:
1 | - operand |
where...
operand | is a primitive numeric type or a wrapper type
corresponding to a primitive numeric type (such as Integer
or Double ). A primitive numeric type is any
primitive type other than boolean , that is, any of the
following types:
|
1 Unary minus expression.
The unary minus operator can take any primitive numeric type (byte
,
short
, char
, int
, long
,
float
, or double
) as its operand, but can
also take any corresponding wrapper type (Byte
, Short
,
Character
, Integer
, Long
, Float
,
or Double
). If a wrapper type is provided, the type is
first unboxed into its primitive counterpart.
int
" or
the negation occur. For example, Integer x = Integer.valueOf(123); // Variable x stores an Integer object that represents the value 123
System.out.println(-x); // x is "unboxed" into 123 as an int
The above code is equivalent to:
Integer x = Integer.valueOf(123);
System.out.println(- (int) x);
That is to say that the operand of -
is converted to its
primitive form, if necessary.
After unboxing (if necessary), if the operand is a byte
, short
,
or char
, then integer promotion occurs: The type is
converted to int
. Since the int
type can
always represent all of the values of each of these 3 smaller types, no
change in value ever occurs during this promotion process.
The type of a unary minus expression is the promoted, primitive type of the input (that is, the type of the input after unboxing then integer promotion are performed, if necessary).
The unary minus operator negates its input. For most numbers, this transformation is trivial.
The minimum values of integer types int
and long
are: -2147483648
and -9223372036854775808
respectively. Performing the unary minus operation on either of these
values will cause overflow and result in the same value.
int
for -2147483648
,
and there is no corresponding positive long
for -9223372036854775808
.
Because of this, trying to negate either value would result in the
maximum positive value plus 1
for the respective type,
which overflows to the minimum value. For example, negating -2147483648
,
would result in 2147483648
(which is the maximum
value of an int: 2147483647
, plus 1), which then simply
overflows back to -2147483648
.
Resultingly, negating the minimum int
or long
value results in the same value.
For floating point values (float
and double
),
the unary minus operator simply flips the sign bit. This results in a
normal, mathematic negation for any floating point value except for NaN
;
the negation of NaN
is NaN
.
Note that negating floating point zero (0.0
) will result
in negative zero (-0.0
), and negating negative zero
results in positive zero. Floating point types differentiate between
negative and positive zero.
This example uses the unary minus operator twice, once per line:
int x = -14;
System.out.println(-x);
Output:
14
Applying the unary minus operator to a value twice will always result
in the same numeric value, though the type will be promoted if
it's smaller than int
:
System.out.println(- -10); // Prints 10
int minInteger = -2147483648; // Lowest possible integer
System.out.println(- -minInteger); // Prints -2147483648
System.out.println(- -0.0); // Prints 0.0
System.out.println(- -0.0d); // Also prints 0.0
Output:
10
-2147483648
0.0
0.0
Because of this, double negation is effectively equivalent to an application of the unary plus operator.
The result of double-negating a value is always that same value, but
if the value is a floating point NaN
, equality
comparisons will always result in false
:
double x = 0.0 / 0; // x is equal to NaN
System.out.println(x == - -x); // Prints false, despite x and - -x being the same value.
Output:
false
This is because an equality check between two NaN
values
always results in false
.
The type of a unary minus expression is partially controlled by the type of the operand expression.
public static void main(String[] args) {
System.out.println("Types of primitive invocations:");
test(-(byte) 1); // int
test(-(char) 1); // int
test(-(short) 1); // int
test(-(int) 1);
test(-(long) 1);
test(-(float) 1);
test(-(double) 1);
System.out.println("\nTypes of wrapper invocations:");
test(-Byte.valueOf((byte) 1)); // int
test(-Character.valueOf((char) 1)); // int
test(-Short.valueOf((short) 1)); // int
test(-Integer.valueOf(1)); // int
test(-Long.valueOf(1)); // long
test(-Float.valueOf(1)); // float
test(-Double.valueOf(1)); // double
}
static void test(byte in) {
System.out.println("byte");
}
static void test(char in) {
System.out.println("char");
}
static void test(short in) {
System.out.println("short");
}
static void test(int in) {
System.out.println("int");
}
static void test(long in) {
System.out.println("long");
}
static void test(float in) {
System.out.println("float");
}
static void test(double in) {
System.out.println("double");
}
Output:
Types of primitive invocations:
int
int
int
int
long
float
double
Types of wrapper invocations:
int
int
int
int
long
float
double
In the above example, the test(int)
, test(long)
,
test(float
, and test(double)
methods are
called, which is why the output contains only int
, long
,
float
, and double
. The test(byte)
,
test(char)
, and test(short)
methods do not
get called at all. The type of the unary minus expression is either int
,
long
, float
, or double
,
depending on the argument.