Confusing type casting in Java [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Weird java behavior with casts to primitive types
Let's look at the following code snippet in Java.
package typecasting;
final public class TypeCasting
{
public static void main(String[] args)
{
int i = (byte) + (char) - (int) + (long) - 1;
System.out.print("\n i = "+i+"\n");
}
}
The statement System.out.print("\n i = "+i+"\n"); displays i = 1. How?

This code uses the unary + and - operators.
It's equivalent to -(-1) with a bunch of extra casts. (the unary + operator doesn't change the value)

The line:
(byte) + (char) - (int) + (long) - 1;
is being parsed as:
(byte) (+(char) (-(int) (+(long)(-1) ) ) );
All the + and - are unary operators. Since there are two -, the 1 gets negated twice so the entire expression evaluates to 1.

The operators are being treated as unary + and unary -.
int i = (byte) (+ (char) (- (int) (+ (long) (- 1))));

The JLS specifies the following:
CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus
This means that any expression that is (Primitive Type) is followed by a UnaryExpression. If I take your statement and put [] around the unary expressions:
(byte)
[+(char)
[-(int)
[+(long)
[-1]
]
]
];

Related

Java - why won't char '+' appear on the console? [duplicate]

This question already has answers here:
In Java, is the result of the addition of two chars an int or a char?
(8 answers)
Closed 2 years ago.
I am making a simple calculator and here is my code.
public static void main(String[] args) {
int x = 3;
int y = 7;
char w = '+';
System.out.println(x+w+y+"="+(x+y));
}
The result appears as '53 = 10' and I don't get why '+' won't appear and where 53 came from. The correct result '3+7=10' appears when I use (w) instead of w at the last line.
chars are implicitly convertible to integers in Java. x + w + y adds their values. The integer value of the character '+' happens to be 43, so you get 3 + 43 + 7 (= 53).
Putting the w into parentheses does not change that, contrary to what you said.
To fix this, make w into a String:
String w = "+";
this behavior is due the fact that the expression
x + w + y
is actually evaluated as 3 + 43 + 7, why, you may want to know? well because + is a char which is actually a number and 43 is is't value as integer.

Does the minus symbol preceding a variable make the first variable negative?

We are asked to use for int variables to make the answer equal 20. We are only supposed to change the placement of the plus's and minuses. They have a minus in front of int a. Does that make int a negative?
I've googled the answer but my Googlefu isn't up to par.
public static int a = 1;
public static int b = 3;
public static int c = 9;
public static int d = 27;
public static void main(String[] args) {
int result = - a + b - c + d;
}
In the expression:
- a + b - c + d
there are 3 different operators, going left to right:
Unary minus operator
Binary plus operator
Binary minus operator
(Binary plus operator again)
In general, unary operators have higher precedence than binary operators, so this expression is equivalent to:
(( (- a) + b) - c) + d
So, the unary - applies to the a. From the linked specification above:
At run time, the value of the unary minus expression is the arithmetic negation of the promoted value of the operand.
So, it doesn't make a negative, it results in an expression whose value is the negation of a. This happens to be negative, because a has a positive value. However, it doesn't make a anything, a is left unchanged.
The only way to actually make a negative would be to reassign it:
a = -Math.abs(a);
For a more elaborate answer please have a look at the java language specification, where you can find detailed information on how operators and expressions are evaluated in java (in your case: https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.15.4)

Java syntax - extra plus sign after cast is valid?

So I came across something that confused me when casting a byte to char, usually I would do this:
for (byte b:"ABCDE".getBytes()) {
System.out.println((char)b);
}
Which will print out
A
B
C
D
E
I accidentally left a + between the (char) and b and got the same result!?
Like so:
for (byte b:"ABCDE".getBytes()) {
System.out.println((char) + b);
}
Why exactly is this happening?
Am I essentially doing (char)(0x00 + b)? Because
System.out.println((char) - b);
yields a different result.
Note: Using Java version 1.8.0_20
Why exactly is this happening?
If you put a unary - operator before a number or expression it negates it.
Similarly, if you put a unary + operator before a number or expression it does nothing.
A safer way to convert a byte to a char is
char ch = (char)(b & 0xFF);
This will work for characters between 0 and 255, rather than 0 to 127.
BTW you can use unary operators to write some confusing code like
int i = (int) + (long) - (char) + (byte) 1; // i = -1;
b is a byte, and that be expressed as + b as well. For example, 3 can be written as +3 as well. So, ((char) + b) is same as ((char) b)
The + is the unary plus operator - like you can say that 1 is equivalent to +1, b is equivalent to +b. The space between + and b is inconsequential. This operator has a higher precedence than the cast, so after it's applied (doing nothing, as noted), the resulting byte is then cast to a char and produces the same result as before.

what does " |= "and " ^= " mean in java? [duplicate]

This question already has answers here:
What does this sign exactly mean? |=
(5 answers)
Closed 8 years ago.
this is a function for changing bit value of image. what does |= and ^= mean?
private int setBitValue(int n,int location,int bit) {
int toggle=(int)Math.pow(2,location),bv=getBitValue(n,location);
if(bv==bit)
return n;
if(bv==0 && bit==1)
n|=toggle; // what does it do?
else if(bv==1 && bit==0)
n^=toggle; // what does it do?
return n;
}
Its the same short form as in +=
n |= toogle
is the same as
n = n | toogle
the | is here the binary-or operator
and ^ is the binary xor-operator
They are short hand assignment operations.
n|=toggle; is equivalent to n=n|toggle;
and
n^=toggle; is equivalent to n=n^toggle;
And
| is bitwise OR
^ is bitwise XOR
They're the bitwise OR equals and the bitwise XOR equals operators. They are mainly used for dealing with bit flags. I highly recommend this article if you want to learn more about bitwise and bit-shifting operations.
These are shorthand bitwise operators. Like += using |= is the same as:
a = a | b;
Read the Oracle Documentation about Bitwise and Bit Shift Operators for further information.

Compilation error: casting

Can somebody explain me why the following piece of code fails to compile. The error is: "Possible loss of precision." :
byte a = 50;
byte b = 40;
byte sum = (byte)a + b;
System.out.println(sum);
Thank you.
Note that the cast has a higher precedence than the + operator. Your code does this:
byte a = 50;
byte b = 40;
byte sum = ((byte)a) + b;
System.out.println(sum);
The cast is redundant, since a is already a byte. You probably meant this:
byte a = 50;
byte b = 40;
byte sum = (byte) (a + b);
System.out.println(sum);
Because the two byte variables are operands to +, they are implicitly promoted to int. This is called Numeric Promotion. Because int is larger than byte, and the result of a + b yields int, casting to byte possibly chops off some bits, as int is larger than byte. Hence the "loss of precision"
Doc for implicit numeric promotion:
http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983
Doc for the size of types:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
You did right by identifying that a cast is required, but unfortunately you did not apply it to the right expression due to precedence of operators.
Consider the following snippet:
static void f(char ch) {
System.out.println("f(char)");
}
static void f(int i) {
System.out.println("f(int)");
}
public static void main(String[] args) {
char ch = 'X';
f( (char) ch + 1 ); // prints "f(int)"
f( (char) (ch + 1) ); // prints "f(char)"
}
The cast has a higher precedence than the addition, which is why the snippet prints what it does. That is, the first call is equivalent to f( ((char) ch) + 1 );. The result of the addition is an int, which is why the f(int) overload is invoked.
The lesson here is that you should always use parenthesis unless you're doing a very simple cast. In general, always consider using parentheses to make the order of evaluation explicit, even if they're not necessary. They lead to a better, more readable code.
Bytes are added using "int" arithmetic; thus the result is an int and must be cast back from int to byte, which leads to the possibility of truncation.

Categories