0

There is 2-bytes array: private byte[] mData;

and method:

public void setWord(final short pData) {
        mData[0] = (byte) (pData >>> 8);
        mData[1] = (byte) (pData);
}

I wrote the simple test:

public void testWord() {
        Word word = new Word();
        word.setWord((short) 0x3FFF);

        Assert.assertEquals(0x3F, word.getByte(0));
        Assert.assertEquals(0xFF, word.getByte(1));
}

The second assert fails with message "Expected 255, but was -1". I know, that 0xFF signed short is, in fact, -1, but why JUnit thinks, that they are not equal? And, what is the correct way to implement such classes?

artem
  • 16,382
  • 34
  • 113
  • 189
  • 1
    Isn't the constant `0xff` an int? Which means that your second argument will be automatically cast to int. – biziclop Jun 21 '11 at 21:52
  • I hate the lack of unsigned ints. This question is about that. http://stackoverflow.com/questions/430346/why-doesnt-java-support-unsigned-ints – aalku Jun 21 '11 at 22:27

3 Answers3

2

The comment from biziclop is correct. Any Integer number you specify in your code is considered an Integer unless marked otherwise.

Change your assertion to:

Assert.assertEquals((byte)0xFF, word.getByte(1))

And it should pass fine - as the first two bytes of the integer will be considered as a byte.

Bitwize speeking - basically when you write 0xFF the compiler interprets it as 0x000000FF which is 255. You want 0xFFFFFFFF which is -1.

Casting to byte is the correct solution here

RonK
  • 9,472
  • 8
  • 51
  • 87
  • That's not completely true. 1.0 is a float and I think a number greater than Integer.MAX_VALUE is recognized as long. – aalku Jun 21 '11 at 21:58
  • Thanks for the comment - I added the word 'Integer' after "Any". As for numbers greater than MAX INT - unless specifically marked with `l` to specify they are `long` - it will not compile – RonK Jun 21 '11 at 22:07
2

Java does not support unsigned types, so in order for a value to be 255, it must not be a signed byte, which is incapable of holding the value of 255. The 0xFF constant value will be taken as a signed int, and for the comparison, the byte value 0xFF will be converted to an int at -1 as well.

You need to type cast the literal 0xFF to be a byte. Change the assert to be Assert.assertEquals((byte)0xFF, word.getByte(1)); Then the left hand side will evaluate to -1 as well as the right.

Akh
  • 632
  • 1
  • 6
  • 15
1

There are no unsigned types in java.

0xFF is the int 255 and casted to byte overflows to -1.

I usually work with bytes as integers if I want them unsigned. I usually do that this way:

int b1 = getByte() & 0xFF;

For example:

byte byte1 = 0xFF; // 255 = -1
byte byte2 = 0xFE; // 254 = -2
int int1 = (byte1 & 0xFF) + (byte1 & 0xFF); // 255 + 254 = 509
aalku
  • 2,860
  • 2
  • 23
  • 44