It's not a secret anymore!*
The moose likes Beginning Java and the fly likes Assigning a byte to a long Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Assigning a byte to a long" Watch "Assigning a byte to a long" New topic
Author

Assigning a byte to a long

Helmut Lerch
Ranch Hand

Joined: Feb 11, 2001
Posts: 48
Hi,
I' m not very used to bit arithmetic. I need to assign a byte to a long.
long l = 0xFF; //255
byte b = 0xFF;
l = b //-1
I know it's something about two's complement and signed/unsigned,
but I don't know how to solve.
Thanks for help
Helmut
Mikael Jonasson
Ranch Hand

Joined: May 16, 2001
Posts: 158
Try casting it.
/Mike
Helmut Lerch
Ranch Hand

Joined: Feb 11, 2001
Posts: 48
Hi,
Originally posted by Mikael Jonasson:
Try casting it.
/Mike

some things I have tried:
<pre>
public class AssignByteLong {
public static void main(String[] args) {
byte b = (byte)0xFF;
long l = 0xFF;
System.out.println("b = 0xFF: b = " + b); // -1
System.out.println("l = 0xFF: l = " + l); // 255
l = 0;
l = b;
System.out.println("l = b: l = " + l); // -1
l = 0;
l = (b);
System.out.println("l = (b): l = " + l); // -1
l = 0;
l = ((long)b);
System.out.println("l = ((long)b): l = " + l); // -1
l = 0;
l |= b;
System.out.println("l |= b: l = " + l); // -1
l = 0;
l = (b << 1);<br /> System.out.println("l = (b << 1): l = " + l); //-2<br /> l = 0;<br /> l = (b >> 1);<br /> System.out.println("l = (b >> 1): l = " + l); //-1
l = 0;
l = (b < 0 ? ((b & 0x7F) | 0x80) : b);
System.out.println("l = ((b & 0x7F) | 0x80): l = " + l); //255
}
}
</pre>
So I have a solution but I think there should be a "better", easier one.
Thanks
Heli
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Heli
If I understand correctly you're trying to take the 0xFF value and put it into a byte then later be able to put the byte into a long and get the 0xFF value back out. If that's not correct then disregard everything after this and repost ...
The code you put up is working the way it should, as soon as you did the first assignment: byte b = (byte)0xFF; you performed a narrowing conversion on the 0xFF - check out the JLS section 5.1.3. In a narrowing conversion only the low order bits of the value being converted are used. In your case the low order 8 bits would be: 11111111 . These would be put in the byte variable and the resulting value is -1. All of the other bits are lost and can't be reclaimed, that's why you couldn't convert it back and get the value 255 after turning it into a long.
When you did that, a widening conversion (JLS section 5.1.2), the value is retained so the long value would be the same as it had been in as a byte, -1.
hope that clears it up for you
------------------
Dave
Sun Certified Programmer for the Java� 2 Platform
[This message has been edited by Dave Vick (edited October 03, 2001).]


Dave
Helmut Lerch
Ranch Hand

Joined: Feb 11, 2001
Posts: 48
Originally posted by Dave Vick:
If I understand correctly you're trying to take the 0xFF value and put it into a byte then later be able to put the byte into a long and get the 0xFF value back out.

Thanks for answering.
The 0xFF value is just an example. It could be any of the other 255 Values of a byte. I am reading a file with read(byte[] b, int off, int len) and I want to put for example two of this bytes in a long. (one in the bits 0 to 7 an the next one in the bits 8 to 15). But I am struggling even with just assigning a byte to a long.
Originally posted by Dave Vick:
All of the other bits are lost and can't be reclaimed, that's why you couldn't convert it back and get the value 255 after turning it into a long.

I thought I don't loose any bits if I assign 0xff to a byte, so conversion back to long should be possible without loss. Am I wrong? A byte has eight bits, 0xff has eight bits set to 1. Of course I just "see" -1 instead of 255 because byte is defined as signed.
Thanks Heli
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Heli
I dont think I explained it very well the first time - sorry
You dont lose any bits when you convert 0xFF to a byte but, like you said, the byte is signed so all it knows is that its most significant bit is 1 so it must be a negative number. When it widens it to a long it does it exactly like it is supposed to and takes the value of the byte and puts it in the long. The key word here is the value, from the JLS 5.1.2 "conversions widening from an integral type to another integral type and from float to double do not lose any information at all; the numeric value is preserved exactly."
Your original problem still remains, once you've got an 8 bit number into a byte you'll never be sure what the orginal number was (unless you know before hand that it'll be between -128 and 127). The only thing I can think of to fix this for you would be that once you've got the byte into a long do an unsigned right shift (>>>) of 56, this'll push the 8 bit into the least significant byte and you'll be ok.
Then to add the next byte to the next higher significant byte of your long:
put the next byte into a long
do an unsigned right shift of 48
then take the original long and the second long and | (or) them.
that, I think, will do what you need it to do.
hope it helps

------------------
Dave
Sun Certified Programmer for the Java� 2 Platform
Helmut Lerch
Ranch Hand

Joined: Feb 11, 2001
Posts: 48
Originally posted by Dave Vick:

hope it helps

Thanks for your detailed explanation.
Heli
Eamonn Doherty
Greenhorn

Joined: Sep 04, 2001
Posts: 9
A byte only holds 8 bits, which means you can only store between -128 to 127. So you can't put 0XFF (255) in there.
Mohan K
Greenhorn

Joined: Oct 04, 2001
Posts: 1
Heli
I dont know if this will help u.
but try reading the input as character instead of byte and zero out the higher byte.
eg. instead of
byte b = 0xff ;
use
char c = 0xffff ; // your input stream
long l = 0x00ff & c ;
System.out.println("l = c & 0x00ff: l = " + l); //255
2 problems though:
1. You will be one off when you read the next byte (if you are using absolute positioning to read it will not be a problem)
2. I am not sure if you will run into little endian/big endian formats problems
Helmut Lerch
Ranch Hand

Joined: Feb 11, 2001
Posts: 48
Originally posted by Mohan K:

char c = 0xffff ; // your input stream
long l = 0x00ff & c ;
System.out.println("l = c & 0x00ff: l = " + l); //255

Thanks nice idea. I will think about it although I have to do the conversation between long and char somtimes twice because I need both bytes separatly.
Eamonn: you can assign 0xFF to a byte without loss its just not "interpreted" as 255, its interpreted as -1. Take a look at the reply of Dave Vick, he explain it very well.
Thanks Heli
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9044
    
  10
Mohan K,
Please read this page and reregister. We want you to be able to continue to participate here at JavaRanch.


JavaBeginnersFaq
"Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
 
jQuery in Action, 2nd edition
 
subject: Assigning a byte to a long
 
Similar Threads
Can you Explain this...
convert long to byte array and back
CRC calc problem
Casting
Byte order conversion question