byte arithmetic question

This must be simple but I never did much low-level arithmetics and it is driving me nuts. I need to convert a int32, even negative ones, to an unsigned byte array. At first I did it like this:

ByteBuffer.allocate(4).putInt(x).array();

where x is the int in question. Works fine for positive ints but with negative ones it became clear that I was getting from ByteBuffer a signed byte array, e.g., -944441877 is (-57 -76 -11 -21) whereas I want (199 180 245 235), i.e. the result of adding 256 to the original array. Problem is: I can't find how to do that! If I naively add 256 to -21 and cast to byte I get back -21. I tried lotsmore things btu I am running out of time. What is the correct way?

Thanks a lot in advance.

[747 byte] By [xolotla] at [2007-10-3 2:34:34]
# 1
Java does not have unsigned bytes. So you need to reconsider your requirements.
GeneralYerevana at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 2

Please don't post to make such an unhelpful answer! I know Java has no unsigned bytes as such but that was not my question: I am simply trying to emulate software that does and I gave a specific example! Specifically how to turn a negative byte into its "256 complement". No more no less. There has to be a way. To go back to my example, -21 and 235 are both valid byte values: I am asking how I can convert between them, knowing that 235 = 256-21.

Thanks again.

xolotla at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 3
Perhaps you could go **** yourself?
GeneralYerevana at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 4
The answer is that 235 is NOT a valid byte value in Java. So you will need to use ints or something in your emulation.
GeneralYerevana at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 5

> Specifically how to turn a negative byte into its

> "256 complement".

Phrased exactly like that the answer is one of the following

1. You can't do that.

2. That is non-sensical - it already has the correct value.

Perhaps you meant something more general. For instance the following will create the equivalent bits in an integer.

byte b = ...

int i= 0x0ff & b;

jschella at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 6

> Perhaps you could go **** yourself?

Haha. Great.

xolotl, if you dont know how to convert a number to two's complement (or the reverse)

youre in bad shape so you shouldnt really be criticising the merits of

someone's response to you.

http://en.wikipedia.org/wiki/Two's_complement

TuringPesta at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 7

> Please don't post to make such an unhelpful answer! I

> know Java has no unsigned bytes as such but that was

> not my question: I am simply trying to emulate

> software that does and I gave a specific example!

> Specifically how to turn a negative byte into its

> "256 complement". No more no less. There has to be a

> way. To go back to my example, -21 and 235 are both

> valid byte values: I am asking how I can convert

> between them, knowing that 235 = 256-21.

>

If you have a byte holding the value 0xFF and you want to get +255, you have to use an int (or a long or a short, I guess). That byte can never have the value +255.

int ii = bb & 0xFF;

bb is a byte with 0xFF, which is -1 for a byte.

ii is an int with 0x000000FF, which is +255 for an int.

jverda at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 8
> > way. To go back to my example, -21 and 235 are> both> > valid byte values:Not in Java. No byte in Java can have the value 235. All bytes in Java always have a value in the range -128..127. This is what it means when we say that "bytes are signed."
jverda at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 9
To recap replies 1,4 5 and 7.You need to use another datatype in your code to perform whatever operations you want. So perhaps my answer wasn't so unhelpful after all.
GeneralYerevana at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 10

yea, but jverd i think the OP is trying to used a signed byte to hold

an unsigned byte which is possible. and apparently they dont

understand two's complement....

@OP:

0000 0000 -> 1111 1111

0 -> 256

(in 2s its -128 to 127)

in 2s complement going up throught the values youll have

0 to 127 and then the next number will be -128 which will decrement to -1

it should be trivial for you to code a conversion now.

from the wikipedia article:

127 = 0111 1111

64 = 0100 0000

1 = 0000 0001

0 = 0000 0000

−1 = 1111 1111

−64 = 1100 0000

−127 = 1000 0001

−128 = 1000 0000

or in order:

0 = 0000 0000

127 = 0111 1111

−128 = 1000 0000

−1 = 1111 1111

Message was edited by:

TuringPest

TuringPesta at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 11

> yea, but jverd i think the OP is trying to used a

> signed byte to hold

> an unsigned byte which is possible.

Right. A byte is a byte. 0xFF is 0xFF. Whether it's -1 (signed) or 255 (unsigned) depends on how you interpret it. If he just wants the byte, then there is no signed/unsigned issue. But if he wants the numerical value 255, then he must use a wider type.

jverda at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 12

Right, I should have checked the definition of signed and unsigned bytes first; I thought they had different widths. With 235 not a valid signed byte, no wonder I had trouble.

> A byte is a byte. 0xFF is 0xFF. Whether it's -1 (signed) or 255 (unsigned)

> depends on how you interpret it.

Thanks. That was more helpful. Funny how all I got at first was a smug answer but after I kicked you all jumped in ;-)

xolotla at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 13

Dont get it twisted xolotl, lol. This:

"Java does not have unsigned bytes. So you need to reconsider your requirements. "

...did not seem to be a smug answer. GeneralYerevan seems to give

good helpful replies to everyone. Your "dont respond with unhelpful

answers" was a little uncalled for.

I (and id assume jverd) didnt give a response b.c. you "kicked" but

rather b.c. i didnt come on to the forums until after that little exchange.

remember, the simplest explanation is usually the best : )

TuringPesta at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 14
> > Thanks. That was more helpful. Funny how all I got at> first was a smug answer What smug answer? You got a perfectly reasonable answer for reply 1, and then you got all snitty.
jverda at 2007-7-14 19:33:32 > top of Java-index,Java Essentials,Java Programming...
# 15
> I (and id assume jverd) didnt give a response b.c.> you "kicked" Correct. I responded despite his snitty response to reply 1, not because of it.
jverda at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 16

> > > way. To go back to my example, -21 and 235 are

> > both

> > > valid byte values:

>

> Not in Java. No byte in Java can have the value 235.

> All bytes in Java always have a value in the range

> -128..127. This is what it means when we say that

> "bytes are signed."

Maybe I am missunderstanding the OP but...

Doesn't he already have what he wants - the 32 bits of the int stored in 4 bytes. Who cares if Java interprets the 8 bits in a byte as signed; if they are being passed to another system they are just bit patterns that the other system can interpret any way it likes.

Opps, I did not see that there was a second page.

Never mind.

Message was edited by:

jbish

jbisha at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 17

> > > > way. To go back to my example, -21 and 235 are

> > > both

> > > > valid byte values:

> >

> > Not in Java. No byte in Java can have the value

> 235.

> > All bytes in Java always have a value in the range

> > -128..127. This is what it means when we say that

> > "bytes are signed."

>

> Maybe I am missunderstanding the OP but...

> Doesn't he already have what he wants - the 32 bits

> of the int stored in 4 bytes. Who cares if Java

> interprets the 8 bits in a byte as signed; if they

> are being passed to another system they are just bit

> patterns that the other system can interpret any way

> it likes.

That's what I thought too. I didn't look closely at how he wants to use them. If it's just to extract and pass around the bytes, then it doesn't matter whether they're signed or unsigned. If he wants to display or manipulate them numerically, then he'll need to decide whether he wants a signed interpretation--in which case he can use them as-is--or an unsigned interpretation--in which case he'll have to stuff them into a wider data type.

jverda at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 18

ok ok maybe I have a bad hair day because of this requirement of emulating the behaviour of a piece of C# code: superficially very similar languages and libraries but with subtle differences. bit-for-bit emulation is always very tricky.

In the end the observation that a byte is a byte was really key: I do get the same results from using (-21 -11 -76 -57) on the Java side and (235 245 180 199) on the C# side. What I had overlooked is that the bytes are returned in opposite order! E.g., in C# BitConverter.GetBytes(-944441877) returns (235 245 180 199) whereas in Java ByteBuffer.allocate(4).putInt(-944441877).toArray() returns (-57 -76 -11 -21) and not (-21 -11 -76 -57) . I am not sure whether you can speak of the endianness of a VM but if you can, then the JVM and the CLR have opposite setups. After flipping the byte array on the Java side I am fine now. At last ;-)

xolotla at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 19
> I am not sure whether you can speak of the endianness> of a VMYes, you can. Just as you can speak of the endianness of a physical CPU, so can you speak of the endianness of a virutal CPU--the JVM. The JVM is big-endian, I believe. I'm sure it's in the spec.
jverda at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 20

Actually if you search the JLS (PDF, 3rd ed.) for "endian" it will come back empty. The BigInteger javadocs do mention that big-endian order is expected, though.Thus, like the ZBSIJ encoding of primitive types in the class name, it seems to be one of those "quasi-spec" properties that are not actually in the spec ;-(

xolotla at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 21
Im positive that the VM is always big-endian regardless of the OS.why the hell is C# little-endian? idiots...
TuringPesta at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 22

> Actually if you search the JLS (PDF, 3rd ed.) for

> "endian" it will come back empty.

It would be in the VM spec, not the JLS, I think. Analogously, C is neither big- nor little-endian. The compiler has to turn it into the right endian for the underlying hardware. The VM serves the role of the hardware here, so its spec would specify endianness, I think.

I'm almost certain that the format is spelled out, even if the word "endian" isn't used.

jverda at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 23
I just read something that confirmed C# is LE.Most likely because PC processors (Intel) are LE.
TuringPesta at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 24
Yes, you are right of course: I should have looked it up in the VM spec. I just did and there is a "big-endian order" index entry there.
xolotla at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...
# 25
TuringPest, what is LE: C# or the CLR?
xolotla at 2007-7-21 9:55:28 > top of Java-index,Java Essentials,Java Programming...