Author Topic: ranges of ints, bytes, shorts, chars  (Read 1220 times)

0 Members and 1 Guest are viewing this topic.

Offline chlortho

  • /dev/null
  • *
  • Posts: 11
  • Cookies: 1
    • View Profile
ranges of ints, bytes, shorts, chars
« on: June 13, 2014, 11:12:32 pm »
I am relatively new so there is a good chance I'm not grasping something.  However, I don't even know if I am asking this question properly... hahaha...  but, here she goes!

Since the range of an int covers the range of char, byte, and short, in that, when a term exceeds the range of char, byte, and short, java automatically converts the operand to int, what is the need for byte, short, char operands (in terms of expressions or intermediate terms)?
chlortho

Offline chapp

  • Peasant
  • *
  • Posts: 87
  • Cookies: 2
    • View Profile
Re: ranges of ints, bytes, shorts, chars
« Reply #1 on: June 13, 2014, 11:15:44 pm »
I am relatively new so there is a good chance I'm not grasping something.  However, I don't even know if I am asking this question properly... hahaha...  but, here she goes!

Since the range of an int covers the range of char, byte, and short, in that, when a term exceeds the range of char, byte, and short, java automatically converts the operand to int, what is the need for byte, short, char operands (in terms of expressions or intermediate terms)?

The short answer is to prevent bugs.

You can read more about type systems at http://en.wikipedia.org/wiki/Type_system

Offline sherlock

  • /dev/null
  • *
  • Posts: 7
  • Cookies: 2
    • View Profile
Re: ranges of ints, bytes, shorts, chars
« Reply #2 on: June 14, 2014, 08:33:14 pm »
There are two main reasons, i can think of:

Firstly using a smaller datatype requires less space (ram) at runtime.
However in practice people tend to prefer int to short, simply because they are used to using int and for normal applications it won't make much of a difference.

Secondly - and in my opinion often that's the more important reason - it increases the readability of code immensely.  E. g. if a variable is declared as a char, you know it represents an Character (digit, letter, symbol).
« Last Edit: June 14, 2014, 08:35:31 pm by sherlock »

Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
Re: ranges of ints, bytes, shorts, chars
« Reply #3 on: June 15, 2014, 09:06:54 am »
I am relatively new so there is a good chance I'm not grasping something.  However, I don't even know if I am asking this question properly... hahaha...  but, here she goes!

Since the range of an int covers the range of char, byte, and short, in that, when a term exceeds the range of char, byte, and short, java automatically converts the operand to int, what is the need for byte, short, char operands (in terms of expressions or intermediate terms)?

The integer types apart from int and char are only important if you:
  • deal with binary formats or low level web requests
  • write embedded applications, e.g. SmarCard programming, where you are short on space
  • you have large arrays containing integers, where a more narrow type can indeed save a lot of space

The char type is another matter, as it has different semantics. Also note that it is unsigned, which the other types aren't. As sherlok noted, marking a variable as char will tell the reader of the code that it is used for characters and (hopefully) nothing else. You should always use types to clarify your semantics to prevent bugs.

Example: I wrote a game where I had to deal with two kinds of location descriptions on the screen. One was the location in pixels, the other the location in game tiles. I did the mistake to use just int x and int y for both of them with the result of having to fix mostly issues that where related to not knowing or forgetting which kind of location i was dealing with right now. Solution: Two data classes, PixelLocation and TileLocation, used like structs to hold the values. I didn't pass (int x, int y) anymore, but PixelLocation or TileLocation, depending which one was used. This really clarified things and it made it impossible to use the wrong type.

Quote
Firstly using a smaller datatype requires less space (ram) at runtime.
However in practice people tend to prefer int to short, simply because they are used to using int and for normal applications it won't make much of a difference.

Unless you have arrays, the JVM won't make a difference handling short, byte or int. Local variables of these types all occupy 32 bit cells within the JVM despite their actual length.
The integer operations are optimized for int values. Using byte or short instead of int is most of the time less efficient as the operations are slower.
Memorywise it is really only a good choice if dealing with very large arrays.

Unless you have performance or memory issues, you shouldn't optimize anyway as it does more harm than good.
« Last Edit: June 15, 2014, 09:11:32 am by Deque »

Offline sherlock

  • /dev/null
  • *
  • Posts: 7
  • Cookies: 2
    • View Profile
Re: ranges of ints, bytes, shorts, chars
« Reply #4 on: June 15, 2014, 12:09:35 pm »
Unless you have arrays, the JVM won't make a difference handling short, byte or int. Local variables of these types all occupy 32 bit cells within the JVM despite their actual length.
The integer operations are optimized for int values. Using byte or short instead of int is most of the time less efficient as the operations are slower.
Memorywise it is really only a good choice if dealing with very large arrays.

In only remembered that it saves space in arrays so i concluded it would save space in variables too, which was wrong.

Regarding space and efficiency:
Code: [Select]
    public int addInts(int x, int y) {
        return x + y;
    }
   
    public short addShorts(short x, short y) {
        // you need the (short) cast since short + short returns an int
        return (short) (x + y);
    }

which compiles to:

Code: [Select]
    public int addInts(int x, int y) {
        iload_1 //loads the int value of x on the stack
        iload_2 //loads the int value of y on the stack
        iadd //pops the two int values on top of the stack (here: x, y) and pushes the sum on the stack
        ireturn //returns the int value on top of the stack
    }

    public short addShorts(short x, short y) {
        iload_1 //loads the int value of x on the stack --> same space as an int in ram needed
        iload_2 //loads the int value of y on the stack --> same space as an int in ram needed
        iadd //pops the two int values on top of the stack (here: x, y) and pushes the sum on the stack
        i2s // converts the int to short --> extra instruction -->less efficient
        ireturn //returns the int (in this case it's a short) value on top of the stack
    }



The reason why there are no extra instructions for datatypes like shorts is explained in the JVM specification:
Quote
Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a byte. Instead, the instruction set of the Java Virtual Machine provides a reduced level of type support for certain operations. In other words, the instruction set is intentionally not orthogonal. Separate instructions can be used to convert between unsupported and supported data types as necessary.
In our example: there are no load, add and return instructions for shorts => the JVM uses the integer ones.

I hope this is more correct.