How is short 128 = byte -128 while explicit casting in java ? - java

import java.util.Scanner;
public class ShortToByte{
public static void main (String args[]){
int i=0;
while (i<6){
Scanner sinput = new Scanner (System.in);
short a = sinput.nextShort();
byte b = (byte) a;
System.out.println("Short value : " + a + ",Byte value : " + b);
i++;
}
}
}
I am trying to understand conversion between different data types, but I am confused as how is short value of 128 = -128 in byte and also how is 1000 in short = -24 in byte ?
I have been using the following logic to convert short to byte :
1000 in decimal -> binary = 0000 0011 1110 1000
while converting to byte : xxxx xxxx 1110 1000 which is equivalent to : 232
I do notice that the correct answer is the two's complement of the binary value, but then when do we use two's complement to convert and when not as while converting 3450 from short to byte I did not use two's complement yet achieved the desired result.
Thank you!

Your cast from short to byte is a narrowing primitive conversion. The JLS, Section 5.1.3, states:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
(bold emphasis mine)
Numeric types are signed in Java. The short 128, represented in bits as
00000000 10000000
is narrowed to 8 bits as follows:
10000000
... which is -128. Now the 1 bit is no longer interpreted as +128; now it's -128 because of how two's complement works. If the first bit is set, then the value is negative.
Something similar is going on with 1000. The short 1000, represented in bits as
00000011 11101000
is narrowed to 8 bits as follows:
11101000
... which is -24.

From java datatypes:
byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive)
Therefore 128 overflows to -128.

Related

Integer Wrapper Class [duplicate]

This question already has an answer here:
Understanding narrowing primitive conversion
(1 answer)
Closed 1 year ago.
Integer Wrapper class
Integer obj = new Integer("1000");
System.out.println(obj.byteValue( )); //-24
I am not able to understand that how this output is formed. I want to understand how this "1000" in an integer is converted into "-24" in a byte. I want to know about the logic behind this.
The docs say:
Returns the value of this Integer as a byte after a narrowing primitive conversion.
which isn't particularly helpful if you don't know what a "narrowing primitive conversion" is. Well, you can look into the Java Language Specification (section 5.1.3) for the definition of that:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T.
The Integer 1000 is represented by 32 bits:
00000000 00000000 00000011 11101000
byte is 8 bits, so we discard all but the 8 lowest order bits, we get:
11101000
which is -24 in 8-bit two's complement binary. -24 = -128 + 64 + 32 + 8
Casting an integer to a byte will give the last 8 bits of of the integer.
1000 in decimal -> 1111101000 in binary
Converting this to a byte value gives you 11101000 which is -24.

Java byte to short convert randomly attached 0xff problem

I am trying to cast from byte to short, but the value is randomly attached to 0xff. Is there a way to handle it normally?
short[] shortArray = new short[size];
for (int index = 0; index < size; index++)
shortArray[index] = (short) byteArray[index];
The negative numbers always must have 1 in leftmost bit.
If byte array has negative numbers, their representation in short format requires left byte to be 0xff to keep the same negative value.
For example:
the decimal byte value -2 is binary 0b1111_1110 or hexadecimal 0xfe
the decimal short value -2 is binary 0b1111_1111_1111_1110 or hexadecimal 0xfffe
Looks like you want to do an unsigned conversion (e.g. got results in range [0..255]).
byte is a signed type in Java, so converting negative byte values to short will produce negative numbers (and in two's complement system you'll see 0xff prefix).
Bit representation, however, is same for signed and unsigned bytes, for example (byte) 0xFF means 255 as unsigned, but is -1 if treated as signed one.
Unsigned conversion can be done by implicit promotion to int, picking 8 low bits using AND and downcasting result to short:
shortArray[index] = (short) (byteArray[index] & 0xFF);

Applying casting to primitive types

int a=128;
byte b;
b=(byte)a;
System.out.println(b);
This prints -128.
But in the Java book the same code outputs 0.
What's the difference between them?
128 represented as a 32-bit integer (int) is 00000000 00000000 00000000 10000000 in binary.
As a byte is only 8 bits, when it is cast to a byte it becomes 10000000. Because all integers in Java are signed integers using two's complement, the first bit (1) is the sign bit, therefore the value becomes -128.
Not sure why the book said the output should be 0. Are you sure the example is exactly the same in the book?
More information on the Java primitives types here and Wikipedia has a fairly comprehensive article on two's complement.
Look, 128 = 0x80, so if you cut off all but less significant byte you will get 1000 0000 (binary). This is -128 for byte.
So there is an error in you java book:)
In Java this should really print -128. If a = 256 it should print 0.
Byte is from -128 to 127, so if you cast 127 it is 127 and 128 is -128 because 127 + 1 = -128.
Right answer was posted already but id like to expand it a little.
To understand better how it works, try to read about it form other sources. #DanielGibbs provided few you could use
i suggest you also try to run code like:
for (int a = -256; a < 256; a++) {
byte b = (byte) a;
System.out.println(a + " -> " + b);
}
output of this code should let you see clearly meaning of less significant (and one most significant which determines sign) bites in int and how they are fit in byte type.
PS. -256 is not 10000000 00000000 00000001 00000000, but 11111111 11111111 11111111 00000000.

How to manually calculate the value of a typecasted byte value that exceeds the primary data type? [duplicate]

This question already has answers here:
java byte data type
(3 answers)
Closed 8 years ago.
since english isn't my main language and i've didn't find any pointers as to how to manually calculate the new number.
Example:
byte b = (byte) 720;
System.out.println(b); // -48
I know that most primary data types use the two complement.
Byte value ranges from -128 to 127, so it's expected to round the number down to something that fits in byte.
The Question is how do i manually calculate the -48 of the typecasted 720? I've read that i have to convert it to two complement, so taking the binary number, searching from right to left for the first one and then inverting all others and since byte only has 8 bits, take the first 8 bits. But that didn't quite work for me, it would be helpful if you would tell me how to calculate a typecasted number that doesn't fit into byte. Thanks for reading! :)
The binary representation of 702 is
10 1101 0000
Get rid of everything except the last 8 bits (because that's what fits into a byte).
1101 0000
Because of the leading 1, get the complement
0010 1111
and add 1
0011 0000
and negate the value. Gives -48.
In Java, integral types are always 2's complement. Section 4.2 of the JLS states:
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers
You can mask out the least significant 8 bits.
int value = 720;
value &= 0xFF;
But that leaves a number in the range 0-255. Numbers higher than 127 represent negative numbers for bytes.
if (value > Byte.MAX_VALUE)
value -= 1 << 8;
This manually yields the -48 that the (byte) cast yields.
First what happens is the value (in binary) is truncated.
720 binary is 0b1011010000
We can only fit 8 bits 0b11010000
first digit 1, so the value is negative.
2's compliment gives you -48.
This is close to redundant with the answer posted by rgettman, but since you inquired about the two's complement, here is "manually" taking the 2's complement, rather than simply subtracting 256 as in that answer.
To mask the integer down to the bits that will be considered for a byte, combine it bitwise with 11111111.
int i = 720;
int x = i & 0xFF;
Then to take the two's complement:
if (x >> 7 == 1) {
x = -1 * ((x ^ 0xFF) + 1);
}
System.out.println(x);

Java - explicit conversion to char/short

can anyone tell me why this explicit conversion gives different results, even if size of short/char is both 16bits?
package jh;
public class Main {
public static void main(String[] args) {
byte b = (byte)255;
System.out.println("Size of short: " + Short.SIZE);
System.out.println("Size of char: " + Character.SIZE);
System.out.println((int)((short)b));
System.out.println((int)((char)b));
}
}
Output:
Size of short: 16
Size of char: 16
-1
65535
From Java datatypes doc
byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
short: The short data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with byte, the same guidelines apply: you can use a short to save memory in large arrays, in situations where the memory savings actually matters.
char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).
So in short (pardon the pun), bitwise they are the same. But char represents a different numeric value for the same bit pattern as short.
This is also accompanied by the sign extension feature: (byte) 255 is going to mean a byte value, with all bits set (0b11111111), which is -1, in twos complement. When converting upwards, Java does a sign extension operation, so if the sign bit is 0, all the higher bits will be 0 too, but when the sign bit is 1, all higher bits will be 1 too. This now means that -1 will mean -1 in all signed, integer datatypes (0b1111111111111111 for short in this example). But not char - which when has all bits set, equals the positive maximum value - 65535.
byte is signed and only holds values -128..127. When you assign 255 it wraps around and becomes -1.
(short)b is -1.
char however is the only unsigned type in Java, it has values 0..65535, so (char)-1 wraps around again and becomes 65535.
byte b = (byte)255; this assigns the value -1 to b since byte is signed. When you cast -1 to short you get -1. When you cast -1 to char you get 65535 since the range of char lies between 0 and 65535

Categories

Resources