• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

how to shift unsigned binary byte(8bits)?

 
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi all:
I read RHE and met the problem: how to shift a unsigned binary byte?
Suppose I am reading unsigned bytes from a IO port, then I want to right shift them 1 bit, since this is a device application, I must use byte(8 bits) to interact with binary bits. but the integal promotion break this. Java treat the 0x91 as a -111 and fills the high 24 bits with 1.(0xffffff91) so :
<code>byte buf=(byte)IOPort.read();//such as 0x91, so explicity cast
buf>>>=1);<code>
becoz of the integal promotion, the 0x91 firstly be converted to 0xffffff91, after right shifting it 1 bit, I get the 0x7fffffc8, cast it to byte, I get a 0xc8 finally. it is not the 0x48 what I expect.
10010001byte buf=0x91;
1111111..110010001integal promotion, buf to int
0111111..111001000right shift 1 bit
11001000cast to byte.
this is what I expect:
10010001a unsigned binary byte
01001000after right shift
what can I do if I must deal with 8bits data?
 
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok Here is an idea, try this
In order to achieve b >> n // where n is number of bits, b is the byte
try
(~(~b | 0xFFFFFF00)) >> n // n is number of bits
Let me try to explain what I am doing here with your example, it will work with any byte
first
b is promoted to integer so 0x91 -> 0xffffff91
~b is 0x0000006E
0x0000006E | 0xFFFFFF00 is 0xFFFFFF6E
~0xFFFFFF6E = 0x00000091
now we do the shift say shift by 4 we get
0x00000091 >> 4 = 0x00000009 which when cast to byte results in 0x09 and which is the correct result. Hope you are able to work with that, I am sure all other intelligent people here will be able to come up with a much elegent solution.

 
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Yin Ming:
hi all:
Java treat the 0x91 as a -111 and fills the high 24 bits with 1.(0xffffff91) so :


Hi
Why 0x91 is treated as -111 ??
Thanks in advance
------------------
Regards
Ravish
 
vinay jain
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another Suggestion which might be easier than the last one is use readUnsignedByte() to read your byte from the I/O port and then you can do all your shifting opoerations on them and convert them back to byte without a problem.
 
Yin Ming
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by ravish kumar:
Hi
Why 0x91 is treated as -111 ??
Thanks in advance



try this:
<code>byte b=(byte)0x91;
System.out.println(b);<code>
0x91 = 10010001
this is the binary form of -111.
 
Yin Ming
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanx to jain. that's a good idea.
follow your point, I find this is better:
<code>b=(byte)((b&0x000000ff)>>>1);<code>
b & 0x000000ff that clear the hight 24 bits but remain the lower 8 bits.
your second post seid the "readUnsignedByte()", do you mean return a int such as 0x00000091? that's good too. what a clever guy!
thanx alot.
 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Yin Ming:

try this:
<code>byte b=(byte)0x91;
System.out.println(b);<code>
0x91 = 10010001
this is the binary form of -111.


Hi Yen
Thanks!! but I wanted to know why after integral promotion 0x91 becomes 0xffffff91 instead of 0x00000091.
Thanks in advance


------------------
Regards
Ravish
 
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Yin Ming:
hi all:
I read RHE and met the problem: how to shift a unsigned binary byte?

10010001byte buf=0x91;
1111111..110010001integal promotion, buf to int
0111111..111001000right shift 1 bit
11001000cast to byte.
this is what I expect:
10010001a unsigned binary byte
01001000after right shift
what can I do if I must deal with 8bits data?


How about:
byte buf = (byte) 0x91;
buf = (byte) ((buf & 0xff) >>> 1);
System.out.println("buf = " + buf);
10010001byte buf=0x91;
1111111..110010001integal promotion, buf to int
0000000..010010001 after "& 0xff"
0000000..001001000right shift 1 bit
01001000cast to byte.
 
Yin Ming
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by ravish kumar:
Hi Yen
Thanks!! but I wanted to know why after integral promotion 0x91 becomes 0xffffff91 instead of 0x00000091.
Thanks in advance
sorry , becoz my badly speaking in English, I cannot explain it clearly. the binary form of 0x91 is :
10010001
U see the highest bit is 1. this is where the negative sign sits. Java thinks that it's a negative number so parses it as a -111. then why does the -111 represent 10010001? its not easy to explain, let me have a try:
the binary form of negative is calculated by these step:
1.first, the positive 111's bit pattern is: 01101111
2.then do the binary not: ~01101111=10010000
3.add 1: 10010000+1=10010001. this is the binary form of -111
this is a fundamental subject of computer. hope this can help


 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Yin Ming:


Hi Yin
Language is never a barrier when two people wants to communicate... and your english is good enough.
Now let us come to the problem again:
I know int & long negative numbers are stored in 2's compliment form. but when we say:
byte buf = 0x91;
internally it should be stored as 0x00000091, as 0x91 is positive number(I think only negative numbers are stored in 2's compliment form, CMIW).
Now when we apply shift operation on 'buf' which is stored as 0x00000091 so it should give desired result.
Thanks in advance again.
Other think which could be possible might be that implementation of shift operation on byte variables could be like that, pick LSB 8 bits from the internally stored integer(out of 64 bits) and then treat it as a number. And again promote it to the integer(64 bits) as per the value of sign bit.
and I think the problem is also coming as 0x91 which is equal to 145 is out of range of byte type. If a number is with in the range of byte then this problem won't be there.
CMIW
------------------
Regards
Ravish
[This message has been edited by ravish kumar (edited November 14, 2001).]
 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the only type which is unsigned is 'char'.
so there is nothing like "unsigned byte".
CMIW

------------------
Regards
Ravish
 
Yin Ming
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by ravish kumar:
I think the only type which is unsigned is 'char'.
so there is nothing like "unsigned byte".
CMIW


yes that's the core of problem.
[This message has been edited by Yin Ming (edited November 15, 2001).]
 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by ravish kumar:

byte buf = 0x91;
internally it should be stored as 0x00000091, as 0x91 is positive number(I think only negative numbers are stored in 2's compliment form, CMIW).
Now when we apply shift operation on 'buf' which is stored as 0x00000091 so it should give desired result.
Thanks in advance again.


Why 0x91 is being stored as 0xffffff91 instaedof 0x00000091 ???
Thanks in advance
------------------
Regards
Ravish
 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
waiting ???
Thanks in advance
------------------
Regards
Ravish
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A byte value 0x91 is stored as a byte of course. It would be incredibly wasteful to store as an int.
HOWEVER - in all shift operations, the value being shifted, if smaller than 32 bits, is promoted to an int before the shift takes place. Therefore you need to use a mask to avoid having the sign bit extended. Something like:
byte b = (byte)0x91 ;
byte c = (byte)( (0xFF & b ) >> 2 ) ;
Bill

------------------
author of:
 
R K Singh
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi william
Thanks a lot, Now it is clear to me why 0x91 becomes 0xffffff91 instaed of 0x00000091.
As JVM just copies the MSB of the byte to other bits of promoted int register.
I think before any operation byte/short is promoted to int.
See the code below:
<pre>
class A011119 {
public static void main(String args[]){
byte b1 = 12;
byte b2 = 14;
byte b3;
b3 = b1 +b2;
System.out.println("b3 = " + b3);
}
}
</pre>
I compile, got this error:

D:\JavaTp\A011119.java:6: Incompatible type for =. Explicit cast needed to convert int to byte.
b3 = b1 +b2;
^
1 error

I do not know how they are stored, But as you say it will really wasteful to store byte/short as int.
I think it(this error) means that before any operation byte/short are converted to int.
CMIW

------------------
Regards
Ravish
[This message has been edited by ravish kumar (edited November 18, 2001).]
 
reply
    Bookmark Topic Watch Topic
  • New Topic