Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Assigning a byte to a long

 
Helmut Lerch
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 158
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try casting it.
/Mike
 
Helmut Lerch
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 3244
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).]
 
Helmut Lerch
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 3244
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Dave Vick:

hope it helps

Thanks for your detailed explanation.
Heli
 
Eamonn Doherty
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 9065
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mohan K,
Please read this page and reregister. We want you to be able to continue to participate here at JavaRanch.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic