Asked  7 Months ago    Answers:  5   Viewed   35 times

When adding 'a' + 'b' it produces 195. Is the output datatype char or int?



The result of adding Java chars, shorts, or bytes is an int:

Java Language Specification on Binary Numeric Promotion:

  • If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed. Then:
  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is converted to long.
  • Otherwise, both operands are converted to type int.

But note what it says about compound assignment operators (like +=):

The result of the binary operation is converted to the type of the left-hand variable ... and the result of the conversion is stored into the variable.

For example:

char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK

One way you can find out the type of the result, in general, is to cast it to an Object and ask it what class it is:

System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer

If you're interested in performance, note that the Java bytecode doesn't even have dedicated instructions for arithmetic with the smaller data types. For example, for adding, there are instructions iadd (for ints), ladd (for longs), fadd (for floats), dadd (for doubles), and that's it. To simulate x += y with the smaller types, the compiler will use iadd and then zero the upper bytes of the int using an instruction like i2c ("int to char"). If the native CPU has dedicated instructions for 1-byte or 2-byte data, it's up to the Java virtual machine to optimize for that at run time.

If you want to concatenate characters as a String rather than interpreting them as a numeric type, there are lots of ways to do that. The easiest is adding an empty String to the expression, because adding a char and a String results in a String. All of these expressions result in the String "ab":

  • 'a' + "" + 'b'
  • "" + 'a' + 'b' (this works because "" + 'a' is evaluated first; if the "" were at the end instead you would get "195")
  • new String(new char[] { 'a', 'b' })
  • new StringBuilder().append('a').append('b').toString()
  • String.format("%c%c", 'a', 'b')
Tuesday, June 1, 2021
answered 7 Months ago

The two operands (1 and 3) are integers, therefore integer arithmetic (division here) is used. Declaring the result variable as double just causes an implicit conversion to occur after division.

Integer division of course returns the true result of division rounded towards zero. The result of 0.333... is thus rounded down to 0 here. (Note that the processor doesn't actually do any rounding, but you can think of it that way still.)

Also, note that if both operands (numbers) are given as floats; 3.0 and 1.0, or even just the first, then floating-point arithmetic is used, giving you 0.333....

Tuesday, June 1, 2021
answered 7 Months ago

The first example (which compiles) is special because both operands of the addition are literals.

A few definitions to start with:

  • Converting an int to char is called a narrowing primitive conversion, because char is a smaller type than int.

  • 'A' + 1 is a constant expression. A constant expression is (basically) an expression whose result is always the same and can be determined at compile-time. In particular, 'A' + 1 is a constant expression because the operands of + are both literals.

A narrowing conversion is allowed during the assignments of byte, short and char, if the right-hand side of the assignment is a constant expression:

In addition, if the expression [on the right-hand side] is a constant expression of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable.

c + 1 is not a constant expression, because c is a non-final variable, so a compile-time error occurs for the assignment. From looking at the code, we can determine that the result is always the same, but the compiler isn't allowed to do that in this case.

One interesting thing we can do is this:

final char a = 'a';
char b = a + 1;

In that case a + 1 is a constant expression, because a is a final variable which is initialized with a constant expression.

The caveat "if […] the value […] is representable in the type of the variable" means that the following would not compile:

char c = 'A' + 99999;

The value of 'A' + 99999 (which is 100064, or 0x186E0) is too big to fit in to a char, because char is an unsigned 16-bit integer.

As for the postfix ++ operator:

The type of the postfix increment expression is the type of the variable.


Before the addition, binary numeric promotion* is performed on the value 1 and the value of the variable. If necessary, the sum is narrowed by a narrowing primitive conversion and/or subjected to boxing conversion to the type of the variable before it is stored.

(* Binary numeric promotion takes byte, short and char operands of operators such as + and converts them to int or some other larger type. Java doesn't do arithmetic on integral types smaller than int.)

In other words, the statement c++; is mostly equivalent to:

c = (char)(c + 1);

(The difference is that the result of the expression c++, if we assigned it to something, is the value of c before the increment.)

The other increments and decrements have very similar specifications.

Compound assignment operators such as += automatically perform narrowing conversion as well, so expressions such as c += 1 (or even c += 3.14) are also allowed.

Friday, June 4, 2021
answered 6 Months ago

In java, a char occupies 16 bit in UTF-16 encoding.

G's unicode is U+0047, in binary 0000 0000 0100 1111.

When you sum a char and an int(32 bit), the char will be converted to int by inserting 0 into the begin of its binary representation. So 0000 0000 0100 1111 is converted to 0000 0000 0000 0000 0000 0000 0100 1111(in decimal, 71).

That's why you get 73.

Tuesday, August 31, 2021
answered 3 Months ago

Because qualifying it with final makes the variable a constant variable, which is a constant expression. So

final byte b = 1;
char c = 2;

c = b; // line 2

actually becomes

final byte b = 1;
char c = 2;

c = 1;

And the compiler has a guarantee that the value 1 can fit in a char variable.

With a non constant byte variable, there is no such guarantee. byte is signed, char is unsigned.

Monday, November 8, 2021
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :