Converting Byte To Int,Short To Long...etc - java

I'm Learning Java and Don't know much about it.
What is the formula of converting from bigger data types to smaller ones?For example:
byte x=10;
long y=250;
x=(byte)y;
System.out.println(x);
after compiling it gives me -6.
and what uses does it have?

You are getting -6 because you made a long to a byte and the value in the long was too big for the byte. Try to convert a byte to a long!
A byte has a range from -128 to 127. A long goes from -2^63 to 2^63-1. You have gotten an overflow becuase of your converting in this way.

a byte can only store at most 256 values however because java is signed, a byte in java stores from -128 to 127.
Your value of 250 is over 127, so it wraps around to negative numbers.
What is the formula of converting smaller data types to bigger ones?
I think you had your variables backwards
y=x;
you don't need to cast since a byte will automatically be expanded into a long

The byte datatype is a signed 1-byte value that may take on values from -128 to 127. When you convert 250l to a byte, Java looks at the binary value 11111010 and shoves that in the byte, but because that first bit is a 1, it's interpreted as a negative value. If you run 11111010 through 2's-complement, you get 110 or 6, so 11111010 is -6.
Short answer: Converting larger datatypes to smaller one gives you hinky results. Don't do it without significant error-checking.

Related

How to calculate the value of any primitive , who has out of range value

Example
byte x;
x=(byte)2355;
System.out.println(x);
so, how can I calculate the value which will be in x;
The 2355 literal value is interpreted as an int, which in Java is represented by the following 32 bits:
00000000000000000000100100110011
A byte has only 8 bits, so you lose the leading 24 bits:
00110011
Converted back to decimal, this leaves you with a value of 51.
You can find the bit sizes of the various primitive data types here. Also keep in mind that you need to take two's complement into account when dealing with signed primitives.
The range of the byte data type is -128 to 127 (inclusive). So if you want to deal with numbers outside that range then you can try casting the data type to short, int or long.

In java, how come method read() from FileInputStream works does not throw " incompatible types: possible lossy conversion"?

I am currently going through Java I/O tutorial and having hard time understanding the read() method of FileInputStream class. I know that per documantion that read() method reads "byte" of data from stream and returns an integer representing the byte (between 0 and 256) or -1 if it reaches the end of file.
Byte in java has a range between -128 and 127, so, how come when I edit xanadu.txt and add ASCI symbol "ƒ" (which has a decimal value of 131), java does not complain by throwing an error that value 131 is out of range defined by byte (-128 and 127)? When I try to test this using literals I get two different results.
The following works:
byte b = 120;
int c = b;
System.out.println((char)c);
Output: x
But this does NOT work (even though it works when added to xanadu.txt):
byte b = 131;
int c = b;
System.out.println((char)c);
Output: error: incompatible types: possible lossy conversion from int to byte
byte b = 131;
I tried explicitly casting using byte: (how is this possible?)
byte b = (byte)131;
int c = b;
System.out.println((char)c);
Output: テ
I am total newbie when it comes to I/O streams, somebody please help me understand it.
EDIT: Turns out my knowledge on concepts of type casting was lacking, specifically in understanding the difference between "Widening" and "Narrowing". Reading up more about these concepts helped me understand why explicit (aka narrowing) casting works.
Allow me to explain: Look at the 3rd code block where I am explicitly casting the literal '131' to type of byte. If we are to convert the literal 131 into binary form of 32-bit signed 2's complement integer, we will get 00000000 00000000 00000000 10000011 which is 32-bits or 4 bytes. Recall that Java data type 'byte' can only hold 8-bit signed 2's complement integer, so, 131 is out of range and thus we get error "possible lossy conversion from int to byte". But, when we explicitly cast it to byte, we are 'chopping off' or correct term would be 'narrowing' the binary down to 8 bit integer. So, when we do that, then the resulting binary is 10000011 which is -125 in decimal value. Since -125 is in range of -128 and 127, byte has no issues accepting and storing it. Now when I try to story the value of byte in int c, implicit or "widening" casting takes place, where -125 in binary form of 8-bit 10000011 is converted into equivalent -125 in binary form of 32-bit 11111111 11111111 11111111 10000011. Finally, system.out is trying to output the value of (char)c which is another explicit or "narrowing" casting where its trying to shrink from 32-bit signed to 16-bit unsigned. When casting is complete, we get 11111111 10000011 in binary form. Now, when this binary is converted into character form by java, it returns テ.
I can conclude by saying that it helps converting everything into binary form and go from there. But make sure you understand encoding and 2's complement
I don't know where you got the value 131 from, but as far as I am concerned, LATIN SMALL LETTER F WITH HOOK (ƒ) is not in the original ASCII character set, but in extended ASCII, with a decimal value of 159. See here. It is also encoded in UTF-16 (how Java chars are encoded) as hex 192 (decimal value 402).
First, ensure that your text files are encoded in extended ASCII, and not UTF-8 (which is the most likely encoding). Then you can use a FileInputStream to read the file, and you will get 159.
Note that 159 is outside the range of the the Java byte type. This is fine, because read returns an int. If the text file is encoded in UTF-8 however, ƒ is encoded in 2 bytes, so read will be reading one byte at a time.
Your second code block doesn't work because as you said, byte goes from -128 to 127, so 131 obviously doesn't fit.
Your third code block forces 131 into a byte, which causes overflow and the value "wraps back around" to -125. b and c are both -125. When you cast this to a char it becomes 65411 because this conversion involves padding the whole number to 16-bits first, then treating it as an unsigned integer.
The reason why this all works when you use FileInputStream.read instead of doing these conversions yourself, is because read actually returns an int, not a byte. It's just that the int it returns will always be in the range -1 ~ 255. This is why we say "read returns a byte", but its actual return type is int.
byte b = 131; // this is 8 bits type, but >8 bits value
int c = b; // this is 32 bits type
System.out.println((char)c); // this is 16 bits type
Output: error: incompatible types: possible lossy conversion from int to byte
byte b = 131;
The two-complement encoding of 131 is:
2^7+2^1+2^0
^^^
sign bit
131 won't fit in a signed byte without an overflow in the two complement representation that is used for signed types. The highest bit=sign bit is set which gets extended when casting from byte to int.
The Java compiler notices that 131 won't fit properly in a byte which leads to the error.

How does overflow work in java?

I've read about overflow, I know that "Overflow is when a number is so large that it will no longer fit within the data type, so the system “wraps around” to the next lowest value and counts up from there".
For example:
short s = (short)1921222; // Stored as 20678
In that example we started counting from -32768 (Short.MIN_VALUE), but when I try to prove in another integer data types, it doesn't seem work the same way...
byte b = (byte)400; // Stored as -112
The example above started counting from 0 that was the only way I found to get -112
I don't know if I am doing something wrong.
The Java Language Specification says:
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, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units.
So, short and byte are both two's complement integers.
short is 16 bits, meaning it can hold 2^16 = 65536 different values. After the 65536th value, it overflows.
1921222 modulo 65536 is 20678 . This is less than 32768 (2^15, the turning point for the two's complement) so we keep a positive number.
byte is 8 bits, meaning it can hold 2^8 = 256 different values. This one overflows after the 256hth value.
400 modulo 256 is 144. This value is higher than 128, the turning point for the two's complement - hence it will be interpreted as a negative two's complement number.
The cast is truncating the number. (JLS)
0000 0001 1001 0000
loses the high byte to become
1001 0000
which is -112.
In java, byte primitive type is an 8 bit signed integer, that's why you got -112 from calling:
byte b = (byte) 400;
You can avoid that and get its un-signed value, by binary adding it with 0xFF like this:
int b = (byte) 400 & 0xFF;
For further details you can check:
Java Primitive data types Documentation.
How to Convert Int to Unsigned Byte and Back
In addition to the other answers, you can get to that answer by manual calculation as well.
In Java, the data type byte is an 8-bit, signed integer. So the values are in the interval [-128, 127]. If you have a value of 400 and you want to see the actual value for that type, you can subtract the size of the interval from that number until you reach a value that's inside the interval.
As I said, byte is 8 bit, so the size of the interval is 256. Subtract that from your initial value: 400 - 256 = 144. This value is still outside of the interval so you have to subtract again: 144 - 256 = -112. This value is now inside the interval and is indeed the value you've seen in your test.
The same is true for your first example: short is 16 bit and signed, so the interval is [-32768, 32767] with size 65536. Doing repeated subtraction from the value 1921222 will eventually give you the value 20678 as seen in your test.

Java Byte, what happens when trying to fit a greater number than 127

I am new to Java but I have been coding in other languages for quite some time. Today I started looking into Java and I noticed an Exception that seems interesting.
When I declare a byte variable and try to store a number smaller than -128 or greater than 127, compiler gives me an error saying
"Type mismatch: cannot convert from int to byte"
Now I know exactly why I can't store lets say 130 in byte for example, but why is the compiler trying to convert from int to byte if I try to assign the value to byte ?
A byte has 8 bits, and its range is -28-1 to 28-1-1 i.e -128 to 127.
This is based on the following equation:
-2n-1 to -2n-1-1,
where n is the number of bits.
You are using values out of range, so a larger data type is needed, for example int.
If you cross the range of particular type, then it is automatically considered an int data type.

How can i convert an integer to byte? [duplicate]

This question already has answers here:
Odd behavior when Java converts int to byte?
(12 answers)
Closed 9 years ago.
I want to know how can i convert an integer to byte theoretically.
I mean i don't want to use a predefined program but i want just to know how can i implement it.
What i know that from -128 to 127 an integer is the same as byte but the problemes is from 128 to 128 to +infinite and from -129 to -infinite.
For example given the following code:
Integer a = 140;//10001100 this is his binary conversion
Byte zz = (byte) a.byteValue();
System.out.println(zz);// result is -116
How that conversion works in java?
Thanks in advance
That value is out of range of the Byte and hence overflows.
Refer JLS 4.2.1:
The values of the integral types are integers in the following ranges:
For byte, from -128 to 127, inclusive
A byte is 8 bits , the most significant bit specifies the sign of the number and are are encoded in two's complement.
Read this wonderful SO answer for more.
when you are narrowing a primitive, you must explicitly make a cast - so you acknowledge a possible loss of data.
There is no loss if value is within the -128...127 byte value range
Byte value binary representation will not change, it will still be 10001100 but it will be interpreted differently, since byte is a signed type in two's complement representation http://en.wikipedia.org/wiki/Twos_complement and since bit 7 is set it means that now it's a negative number -116
You can not convert value grate than 127 into byte as it do not have place to store it. As 140 in binary is 10001100 it mean that you need a type that store at lest 8 bits. A byte store 8 bits but one of then is reserved for sign. So you can not fit it into it. You can use short witch store 16 bits (15 and 1 for sign).
The zero in different types expressed in binary;
byte b = 0b000_0000;
short s = 0b000_0000_0000_0000;
int i = 0b000_0000_0000_0000_0000_0000_0000_0000;
If you try to declare something like:
byte b = 0b1000_1100;
The compiler will tall you Type mismatch: cannot convert from int to byte.

Categories