Comparing byte values doesn't work

G

Guest

Hi,
I have a doubt.Why doesn't the following loop work?
Logically,the if statement should have been satisfied atleast once.

class Test {
public static void main(String[] args) {

for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
if (b == 0x90)
System.out.print("Printed");
}//loop-ends
}
}

It works with:
if(b==(byte)0x90)
But,
0x90 = 00....0000 1001 0000 +144
(byte)0x90 = 1001 0000 -0x70

-0x70 is well within the byte range.Then what makes it unequal to all
byte values?

Thanks in advance.
 
G

Gordon Beaton

-0x70 is well within the byte range.Then what makes it unequal to
all byte values?

The operation is *integer* comparison, so you are comparing each byte
with 0x90 (144), not -0x70.

As you've already discovered, you need to cast 0x90 to byte for the
comparison to succeed.

Read about "binary numeric promotion" here:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5198
http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983

/gordon
 
E

Eric Sosman

Hi,
I have a doubt.Why doesn't the following loop work?
Logically,the if statement should have been satisfied atleast once.

class Test {
public static void main(String[] args) {

for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
if (b == 0x90)
System.out.print("Printed");
}//loop-ends
}
}

It works with:
if(b==(byte)0x90)
But,
0x90 = 00....0000 1001 0000 +144
(byte)0x90 = 1001 0000 -0x70

-0x70 is well within the byte range.Then what makes it unequal to all
byte values?

The range of a byte goes from -128 == -0x80 through
127 == 0x7F. 0x90 == 144 is outside that range: it is
a larger value than any byte can hold, so no byte can
ever be equal to it and the test will never be satisfied.
(byte)0x90 == -0x70 == -112 is within the range of byte
values. (byte)0x90 != 0x90; the first is negative and
the second is positive.

Besides which, your loop leaves one value untested.
 
D

Daniel Pitts

Hi,
I have a doubt.Why doesn't the following loop work?
Logically,the if statement should have been satisfied atleast once.

class Test {
public static void main(String[] args) {

for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
if (b == 0x90)
System.out.print("Printed");
}//loop-ends
}

}

It works with:
if(b==(byte)0x90)
But,
0x90 = 00....0000 1001 0000 +144
(byte)0x90 = 1001 0000 -0x70

-0x70 is well within the byte range.Then what makes it unequal to all
byte values?

Thanks in advance.


Like others have said, the comparison first converts to integers.
0x90 = 192, your loop ranges from -128 to 126.

Two things to do:
for (int b = Byte.MIN_VALUE; b <= Byte.MAX_VALUE; b++) {
if ((byte)b == (byte)0x90) {
System.out.println("Printed");
}
}
 
R

Rajeev Sreedharan

The operation is *integer* comparison, so you are comparing each byte
with 0x90 (144), not -0x70.
(byte)0x90 == -0x70 == -112 is within the range of byte
values. (byte)0x90 != 0x90; the first is negative and
the second is positive.


Thanks, the language specifications helped a lot.


Like others have said, the comparison first converts to integers.
0x90 = 192, your loop ranges from -128 to 126.

Two things to do:
for (int b = Byte.MIN_VALUE; b <= Byte.MAX_VALUE; b++) {
if ((byte)b == (byte)0x90) {
System.out.println("Printed");
}
}

Is the casting of the first operand used to force byte calculations?
I tried println(b) with both ways and got the same result -112.

class Test {
public static void main(String[] args) {

for (int b = Byte.MIN_VALUE; b <= Byte.MAX_VALUE; b++) {
if (b == (byte)0x90) {
System.out.println("Printed");
System.out.println(b);
}
}//loop-ends
}
}
 
G

Gordon Beaton

Is the casting of the first operand used to force byte calculations?

No, the comparison is done using ints. Follow the links I posted.

Byte operands are promoted to int before the comparison is made.
I tried println(b) with both ways and got the same result -112.

What both ways?

I think you'll find that these give different results:

System.out.println(0x90);
System.out.println((byte)0x90);

Casting with (byte)b where b is already a byte doesn't change
anything.

/gordon
 
R

Rajeev

No, the comparison is done using ints. Follow the links I posted.

Byte operands are promoted to int before the comparison is made.


What both ways?

I think you'll find that these give different results:

System.out.println(0x90);
System.out.println((byte)0x90);

Casting with (byte)b where b is already a byte doesn't change
anything.

Yes, i went through the link and soon did conclude that my earlier
loop was
undergoing a byte to integer conversion. But the next post i was
referring
to another snip werein it used
if ((byte)b == (byte)0x90)

Thanks again.
 
C

Chris Uppal

Rajeev said:
[...]
if ((byte)b == (byte)0x90)

I'm not sure if I've understood what you are asking, but I hope this helps...

What that code will do is

1) Cast b to a byte. Since b is already a byte, this has absolutely no effect
and will be ignored by the compiler.

2) Cast 0x90 to a byte, resulting in the decimal byte value -112. (Actually
that will be done at compile-time rather than at runtime, but it makes no
difference here).

3) Convert /both/ byte values to 32-bit integers.

4) Compare those integers.


There is no way that you can compare two bytes directly in Java -- they are
/always/ promoted to integers before the comparison. (And before all other
arithmetic operations, such as subtraction.)

(BTW, if all this seems somewhat overcomplicated to you, then don't worry -- I
think it's overcomplicated too. The real problem is that in Java (against all
good sense) the 'byte' datatype is signed.)

-- chris
 
D

Daniel Pitts

Rajeev said:
Is the casting of the first operand used to force byte calculations?
[...]
if ((byte)b == (byte)0x90)

I'm not sure if I've understood what you are asking, but I hope this helps...

What that code will do is

1) Cast b to a byte. Since b is already a byte, this has absolutely no effect
and will be ignored by the compiler.

2) Cast 0x90 to a byte, resulting in the decimal byte value -112. (Actually
that will be done at compile-time rather than at runtime, but it makes no
difference here).

3) Convert /both/ byte values to 32-bit integers.

4) Compare those integers.

There is no way that you can compare two bytes directly in Java -- they are
/always/ promoted to integers before the comparison. (And before all other
arithmetic operations, such as subtraction.)

(BTW, if all this seems somewhat overcomplicated to you, then don't worry -- I
think it's overcomplicated too. The real problem is that in Java (against all
good sense) the 'byte' datatype is signed.)

-- chris


Actually, you missed (twice) his reference to MY post, in which b is
an int.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top