Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Primitive type 'short' - casting in Java

I have a question about the primitive type short in Java. I am using JDK 1.6.

If I have the following:

short a = 2; short b = 3; short c = a + b; 

the compiler does not want to compile - it says that it "cannot convert from int to short" and suggests that I make a cast to short, so this:

short c = (short) (a + b); 

really works. But my question is why do I need to cast? The values of a and b are in the range of short - the range of short values is {-32,768, 32767}. I also need to cast when I want to perform the operations -, *, / (I haven't checked for others).

If I do the same for primitive type int, I do not need to cast aa+bb to int. The following works fine:

int aa = 2; int bb = 3; int cc = aa +bb; 

I discovered this while designing a class where I needed to add two variables of type short, and the compiler wanted me to make a cast. If I do this with two variables of type int, I don't need to cast.

A small remark: the same thing also happens with the primitive type byte. So, this works:

byte a = 2; byte b = 3; byte c = (byte) (a + b); 

but this not:

byte a = 2; byte b = 3; byte c = a + b; 

For long, float, double, and int, there is no need to cast. Only for short and byte values.

like image 967
user42155 Avatar asked Jan 25 '09 14:01

user42155


People also ask

What is primitive type casting in Java?

Type casting is when you assign a value of one primitive data type to another type. In Java, there are two types of casting: Widening Casting (automatically) - converting a smaller type to a larger type size. byte -> short -> char -> int -> long -> float -> double.

Can Boolean values be cast into any other primitive type?

Casting between primitive types enables you to convert the value of one type to another primitive type. This most commonly occurs with the numeric types. But one primitive type can never be used in a cast. Boolean values must be either true or false and cannot be used in a casting operation.

Which data type Cannot be typecast?

This is most commonly occurs with the numeric data types . But boolean primitive type can never be used in a cast. Its values must be either true or false and cannot be used in a casting operation.

What is primitive data type conversion?

Converting one primitive datatype into another is known as type casting (type conversion) in Java. You can cast the primitive datatypes in two ways namely, Widening and, Narrowing. Widening − Converting a lower datatype to a higher datatype is known as widening.


2 Answers

As explained in short C# (but also for other language compilers as well, like Java)

There is a predefined implicit conversion from short to int, long, float, double, or decimal.

You cannot implicitly convert nonliteral numeric types of larger storage size to short (see Integral Types Table for the storage sizes of integral types). Consider, for example, the following two short variables x and y:

short x = 5, y = 12; 

The following assignment statement will produce a compilation error, because the arithmetic expression on the right-hand side of the assignment operator evaluates to int by default.

short z = x + y;   // Error: no conversion from int to short 

To fix this problem, use a cast:

short z = (short)(x + y);   // OK: explicit conversion 

It is possible though to use the following statements, where the destination variable has the same storage size or a larger storage size:

int m = x + y; long n = x + y; 

A good follow-up question is:

"why arithmetic expression on the right-hand side of the assignment operator evaluates to int by default" ?

A first answer can be found in:

Classifying and Formally Verifying Integer Constant Folding

The Java language specification defines exactly how integer numbers are represented and how integer arithmetic expressions are to be evaluated. This is an important property of Java as this programming language has been designed to be used in distributed applications on the Internet. A Java program is required to produce the same result independently of the target machine executing it.

In contrast, C (and the majority of widely-used imperative and object-oriented programming languages) is more sloppy and leaves many important characteristics open. The intention behind this inaccurate language specification is clear. The same C programs are supposed to run on a 16-bit, 32-bit, or even 64-bit architecture by instantiating the integer arithmetics of the source programs with the arithmetic operations built-in in the target processor. This leads to much more efficient code because it can use the available machine operations directly. As long as the integer computations deal only with numbers being “sufficiently small”, no inconsistencies will arise.

In this sense, the C integer arithmetic is a placeholder which is not defined exactly by the programming language specification but is only completely instantiated by determining the target machine.

Java precisely defines how integers are represented and how integer arithmetic is to be computed.

      Java Integers -------------------------- Signed         |  Unsigned -------------------------- long  (64-bit) | int   (32-bit) | short (16-bit) |  char (16-bit) byte  (8-bit)  | 

Char is the only unsigned integer type. Its values represent Unicode characters, from \u0000 to \uffff, i.e. from 0 to 216−1.

If an integer operator has an operand of type long, then the other operand is also converted to type long. Otherwise the operation is performed on operands of type int, if necessary shorter operands are converted into int. The conversion rules are exactly specified.

[From Electronic Notes in Theoretical Computer Science 82 No. 2 (2003)
Blesner-Blech-COCV 2003: Sabine GLESNER, Jan Olaf BLECH,
Fakultät für Informatik,
Universität Karlsruhe
Karlsruhe, Germany]

like image 155
VonC Avatar answered Sep 24 '22 03:09

VonC


EDIT: Okay, now we know it's Java...

Section 4.2.2 of the Java Language Specification states:

The Java programming language provides a number of operators that act on integral values:

[...]

  • The numerical operators, which result in a value of type int or long:
  • [...]
  • The additive operators + and - (§15.18)
  • In other words, it's like C# - the addition operator (when applied to integral types) only ever results in int or long, which is why you need to cast to assign to a short variable.

    Original answer (C#)

    In C# (you haven't specified the language, so I'm guessing), the only addition operators on primitive types are:

    int operator +(int x, int y); uint operator +(uint x, uint y); long operator +(long x, long y); ulong operator +(ulong x, ulong y); float operator +(float x, float y); double operator +(double x, double y); 

    These are in the C# 3.0 spec, section 7.7.4. In addition, decimal addition is defined:

    decimal operator +(decimal x, decimal y); 

    (Enumeration addition, string concatenation and delegate combination are also defined there.)

    As you can see, there's no short operator +(short x, short y) operator - so both operands are implicitly converted to int, and the int form is used. That means the result is an expression of type "int", hence the need to cast.

    like image 42
    Jon Skeet Avatar answered Sep 23 '22 03:09

    Jon Skeet