I would like to do a data transfer between two computers using datagram socket.Iam using the following line this way :
host=InetAddress.getByAddress("mypc",new byte[]{192,168,1,110});
but when i use the above statement i get this error :"Possible loss of precision"
So i cast the int to bytes this way :
InetAddress.getByAddress("mypc",new byte[]{(byte)192,(byte)168,(byte)1,(byte)110});
Would the above statement work now ???
If you already have it in a string, just use getByName():
InetAddress host = InetAddress.getByName("192.168.1.110");
Using bytes is cluttered, and possibly dangerous (due to signed byts used in Java). Stick with Strings if you can.
There's no problem casting the positive integer literals into byte values, even if they overflow.
The InetAddress.getByAddress() function copes perfectly well with the fact that values exceeding 127 will be converted into negative numbers.
The only thing you need to watch out for is converting the signed bytes back into integers if you subsequently want to display them. This works fine:
byte b = (byte)192;
System.out.println(b); // outputs "-64"
int i = (b & 0xff);
System.out.println(i); // outputs "192"
java bytes are signed (stupid, I know) so larger than 127 is not possible.
See alnitaks' response for a more complete (and later:) answer.
It might not, cos the max value for a byte is 127 and beyond that it would rollover to the negative -64 for 192, -88 for 168 and so on...
Related
I need to sum all data bytes in ByteArrayOutputStream, adding +1 to the result and taking the 2 least significant bytes.
int checksum = 1;
for(byte b : byteOutputStream.toByteArray()) {
checksum += b;
}
Any input on taking the 2 least significant bytes would be helpful. Java 8 is used in the environment.
If you really mean least significant bytes then:
checksum & 0xFFFF
If you meant that you want to take least significant bits from checksum, then:
checksum & 0x3
Add
checksum &= 0x0000ffff;
That will zero out everything to the left of the 2 least significant bytes.
Your question is a bit underspecified. You didn’t say neither, what you want to do with these two bytes nor how you want to store them (which depends on what you want to do).
To get to individual bytes, you can use
byte lowest = (byte)checksum, semiLowest=(byte)(checksum>>8);
In case you want to store them in a single integer variable, you have to decide, how these bytes are to be interpreted numerically, i.e signed or unsigned.
If you want a signed interpretation, the operation is as simple as
short lowest2bytes = (short)checksum;
If you want an unsigned interpretation, there’s the obstacle that Java has no dedicated type for that. There is a 2 byte sized unsigned type (char), but using it for numerical values can cause confusion when other code tries to interpret it as character value (i.e. when printing). So in that case, the best solution is to use an int variable again and only initialize it with the unsigned char value:
int lowest2bytes = (char)checksum;
Note that this is semantically equivalent to
int lowest2bytes = checksum&0xffff;
seen in other solutions.
Let's say I have the following code in java
byte t = (byte) 0b10001000;
byte z = 0b00000000;
z = (byte) (t|z);
You'd think the output would be 10001000, however it ends up being -1111000 in String representation, the - sign being the first 1 of course, making it 11111000. If I do the same code but with the last bit in z as a 1, e.g. 00000001, and I perform the same operation, I get -1110111, or 11110111. I figure this is due to some conversion issue with the negatively signed byte t. Is there any way to avoid this? Is there any way to have 10000000 work the same in an OR operation as 01000000?
Java doesn't have unsigned types, so when you use binary notaion and set the sign bit things will not go as you expect ;-)
To emulate an unsigned type you need to work in the next size up.
I am trying to take hex values and move them into a byte array. When I do this they are not converted how I need them to be. Most of them are converted to negative numbers. For example, after the execution of the C# code "baCommandPDI[0] = 0xD1;", the value of baCommandPDI[0] is "209". This is what I need. No matter what I try in Java, the value is "-47". I need it to be "209" in the byte array, because this byte array is sent out over TCP/IP to some external hardware. The external hardware cannot interpret -47 as 209. It must be 209. I have tried the following code:
int intTemp = 0xD1; After this line is executed the value of intTemp is 209, great!
int intHexValue = 0xD1 & 0xFF; After this line is executed the value of intHexValue is still 209, I don't understand how, but it ia what it is.
baCommand[0] = (byte) intHexValue; After this line is executed the value of baCommand[0] is -47, bad. This is not what I want. Everytime it converts the value to a byte it makes it signed.
Is there any other way I can do this? Can I use 11010001 and some how assign that value to a byte without making it negative?
In Java, bytes are always signed. But like an unsigned byte in another language, 8 bits are still used. The byte representations for 209 (unsigned) and -47 are the same.
1101 0001
The only difference is how Java interprets the most significant bit -- -128 vs. 128 in an unsigned type. The difference is 256, which is the difference between 209 and -47. You can send the value as is, because the bit values are the same, only the interpretations of this bit pattern are different.
If you would like to convert the value -47 to 209 to convince yourself in Java, you can promote the type to a longer primitive type and mask out the last 8 bits. This line will do this is one line, so you can debug and see that the bits are the same and that the unsigned version is equivalent.
int test = baCommandPDI[0] & 0xFF;
Printing/debugging test will let you see the value 209.
Java does not have a concept of unsigned bytes.
To get 209 from 0xD1, try:
0xD1 & 0xFF;
This code
byte b = Byte.parseByte("10000000", 2);
throws an exception in Java. This should be -128 or 255.
Byte has 8 bit. Why can't I parse a 8 bit string?
The reason is down to the range of a byte in Java. Bytes are signed, so you can have anything from -128 ("-10000000") through to 127 ("1111111"), but no values outside that range.
The MAX_VALUE of a byte in java (or in C#) is 127 where as 10000000 return 128 which cannot be stored in a byte variable
What you can do treat the value as signed this way.
byte b = (byte) Integer.parseInt("10000000", 2);
Strictly, you passed not eight bits to parse method, but string representation of usual number with radix 2. And it may contain a sign character. Particularly, byte b = Byte.parseByte("-10000000", 2) works nice and gives -128.
That's not an 8-bit string, it's an 8-character string, and it's not being read the way you think it is...
From the MSDN documentation (here), you'll see that byte.Parse accepts strings in the integer format. So, you're trying to parse 10 million, not -1. The exception you're getting gives this away: you should see an OverflowException.
byte.parse("255") gives the effect you expect (byte is unsigned; using -128 also gives an overflow).
In Java, there is no such thing as an unsigned byte.
Working with some low level code, occasionally you need to work with bytes that have unsigned values greater than 128, which causes Java to interpret them as a negative number due to the MSB being used for sign.
What's a good way to work around this? (Saying don't use Java is not an option)
It is actually possible to get rid of the if statement and the addition if you do it like this.
byte[] foobar = ..;
int value = (foobar[10] & 0xff);
This way Java doesn't interpret the byte as a negative number and flip the sign bit on the integer also.
When reading any single value from the array copy it into something like a short or an int and manually convert the negative number into the positive value it should be.
byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value
You can do a similar conversion when writing into the array.
Using ints is generally better than using shorts because java uses 32-bit values internally anyway (Even for bytes, unless in an array) so using ints will avoid unnecessary conversion to/from short values in the bytecode.
Probably your best bet is to use an integer rather than a byte. It has the room to allow for numbers greater than 128 without the overhead of having to create a special object to replace byte.
This is also suggested by people smarter than me (everybody)
http://www.darksleep.com/player/JavaAndUnsignedTypes.html
http://www.jguru.com/faq/view.jsp?EID=13647
The best way to do bit manipulation/unsigned bytes is through using ints. Even though they are signed they have plenty of spare bits (32 total) to treat as an unsigned byte. Also, all of the mathematical operators will convert smaller fixed precision numbers to int. Example:
short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short
Because of this it is best to just stick with integer and mask it to get the bits that you are interested in. Example:
int a = 32;
int b = 128;
int foo = (a + b) | 255;
Here is some more info on Java primitive types http://mindprod.com/jgloss/primitive.html
One last trivial note, there is one unsigned fixed precision number in Java. That is the char primitive.
I know this is a very late response, but I came across this thread when trying to do the exact same thing. The issue is simply trying to determine if a Java byte is >127.
The simple solution is:
if((val & (byte)0x80) != 0) { ... }
If the real issue is >128 instead, just adding another condition to that if-statement will do the trick.
I guess you could just use a short to store them. Not very efficient, but really the only option besides some herculean effort that I have seen.