Create unsigned byte for serial port use - java

I need to write a java program that will send byte through serial port. I am using the rxtx library. The problem is that in Java everything is signed, and in one byte I need to send 0xfc, but in Java this is signed, and it defined as -4. So how can I make an unsigned byte in java, so that in one byte I can send from 0 to 255?

It's fine - you can just cast where required. If you have an API which lets you send bytes, and you send a byte of -4 in Java, the bit pattern will be the same as for an unsigned byte 0xfc.
If you have a value as an int or short in the range 0-255, just cast that to byte, and again it will represent the right bit pattern, even though the value will become negative if the original value was above 127.

This will work
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}

For a byte b , b & 0xFF will return the unsigned integer value .. will that be okay for you??

Related

unsigned bytes in Java byte array

This may seem like an easy question, but I'm so confused.
byte[] bArray = new byte[]{(byte) (0x80 & 0xff)};
System.out.println(bArray[0]);
and my output is -128. Why?
How can I rewrite this so that the byte array contains 128?
I thought that the 0xff made it unsigned.
Thanks for your help!
I thought that the 0xff made it unsigned.
Well, it does, sort of - it promotes it to an int, and keeps just the last 8 bits.
However, you're then casting the result of that back to a byte, and a byte in Java is always signed. (It's annoying, but it's the way it is.) So you might as well just have written:
byte[] bArray = { (byte) 0x80 };
The result would be exactly the same.
You're storing the bit pattern you want to store (10000000) so if you're transmitting this elsewhere, you don't need to worry... it's just when you're viewing it as a byte in Java that it's annoying.
Value range of byte according Java Language Specification 4.2.1
For byte, from -128 to 127, inclusive
so there is no way (in Java) that a byte will hold (byte) 128.
You can cast the byte to an int and apply & 0xff to get the unsigned representation of the byte (as an int). But if you cast it back to an byte it will again be interpreted as being a signed value between -128 and 127...
If you are only concerned with printing:
System.out.println(bArray[0] & 0xff);
or, for hexadecimal
System.out.printf("0x%02x\n", bArray[0]);
My answer is attached in the big picture

Can unsigned integer vaule is there in java? if then how to declare it? [duplicate]

Is there a way to declare an unsigned int in Java?
Or the question may be framed as this as well:
What is the Java equivalent of unsigned?
Just to tell you the context I was looking at Java's implementation of String.hashcode(). I wanted to test the possibility of collision if the integer were 32 unsigned int.
Java does not have a datatype for unsigned integers.
You can define a long instead of an int if you need to store large values.
You can also use a signed integer as if it were unsigned. The benefit of two's complement representation is that most operations (such as addition, subtraction, multiplication, and left shift) are identical on a binary level for signed and unsigned integers. A few operations (division, right shift, comparison, and casting), however, are different. As of Java SE 8, new methods in the Integer class allow you to fully use the int data type to perform unsigned arithmetic:
In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. Use the Integer class to use int data type as an unsigned integer. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
Note that int variables are still signed when declared but unsigned arithmetic is now possible by using those methods in the Integer class.
Whether a value in an int is signed or unsigned depends on how the bits are interpreted - Java interprets bits as a signed value (it doesn't have unsigned primitives).
If you have an int that you want to interpret as an unsigned value (e.g. you read an int from a DataInputStream that you know should be interpreted as an unsigned value) then you can do the following trick.
int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffL;
Note, that it is important that the hex literal is a long literal, not an int literal - hence the 'L' at the end.
We needed unsigned numbers to model MySQL's unsigned TINYINT, SMALLINT, INT, BIGINT in jOOQ, which is why we have created jOOU, a minimalistic library offering wrapper types for unsigned integer numbers in Java. Example:
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
All of these types extend java.lang.Number and can be converted into higher-order primitive types and BigInteger. Hope this helps.
(Disclaimer: I work for the company behind these libraries)
For unsigned numbers you can use these classes from Guava library:
UnsignedInteger
UnsignedLong
They support various operations:
plus
minus
times
mod
dividedBy
The thing that seems missing at the moment are byte shift operators. If you need those you can use BigInteger from Java.
Perhaps this is what you meant?
long getUnsigned(int signed) {
return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
getUnsigned(0) → 0
getUnsigned(1) → 1
getUnsigned(Integer.MAX_VALUE) → 2147483647
getUnsigned(Integer.MIN_VALUE) → 2147483648
getUnsigned(Integer.MIN_VALUE + 1) → 2147483649
Use char for 16 bit unsigned integers.
There are good answers here, but I don’t see any demonstrations of bitwise operations. Like Visser (the currently accepted answer) says, Java signs integers by default (Java 8 has unsigned integers, but I have never used them). Without further ado, let‘s do it...
RFC 868 Example
What happens if you need to write an unsigned integer to IO? Practical example is when you want to output the time according to RFC 868. This requires a 32-bit, big-endian, unsigned integer that encodes the number of seconds since 12:00 A.M. January 1, 1900. How would you encode this?
Make your own unsigned 32-bit integer like this:
Declare a byte array of 4 bytes (32 bits)
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
This initializes the array, see Are byte arrays initialised to zero in Java?. Now you have to fill each byte in the array with information in the big-endian order (or little-endian if you want to wreck havoc). Assuming you have a long containing the time (long integers are 64 bits long in Java) called secondsSince1900 (Which only utilizes the first 32 bits worth, and you‘ve handled the fact that Date references 12:00 A.M. January 1, 1970), then you can use the logical AND to extract bits from it and shift those bits into positions (digits) that will not be ignored when coersed into a Byte, and in big-endian order.
my32BitUnsignedInteger[0] = (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24); // first byte of array contains highest significant bits, then shift these extracted FF bits to first two positions in preparation for coersion to Byte (which only adopts the first 8 bits)
my32BitUnsignedInteger[1] = (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
my32BitUnsignedInteger[2] = (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
my32BitUnsignedInteger[3] = (byte) ((secondsSince1900 & 0x00000000000000FFL); // no shift needed
Our my32BitUnsignedInteger is now equivalent to an unsigned 32-bit, big-endian integer that adheres to the RCF 868 standard. Yes, the long datatype is signed, but we ignored that fact, because we assumed that the secondsSince1900 only used the lower 32 bits). Because of coersing the long into a byte, all bits higher than 2^7 (first two digits in hex) will be ignored.
Source referenced: Java Network Programming, 4th Edition.
It seems that you can handle the signing problem by doing a "logical AND" on the values before you use them:
Example (Value of byte[] header[0] is 0x86 ):
System.out.println("Integer "+(int)header[0]+" = "+((int)header[0]&0xff));
Result:
Integer -122 = 134
Just made this piece of code, wich converts "this.altura" from negative to positive number. Hope this helps someone in need
if(this.altura < 0){
String aux = Integer.toString(this.altura);
char aux2[] = aux.toCharArray();
aux = "";
for(int con = 1; con < aux2.length; con++){
aux += aux2[con];
}
this.altura = Integer.parseInt(aux);
System.out.println("New Value: " + this.altura);
}
You can use the Math.abs(number) function. It returns a positive number.

How do I convert a Hex value (example: 0xD1) to a unsigned Byte in Java?

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;

Byte buffer in Java?

Since I found out that it's impossible to have unsigned bytes in java, and that essentially they take up the same memory as an int, is there really any difference when you send them over a packet?
If I send a Java byte via tcp or udp via(Games.RealTimeMultiplayer.sendReliableMessage) would that be more beneficial to me than just sending an integer to represent an unsigned byte?
Since I found out that it's impossible to have unsigned bytes in java
This is incorrect. There are lots of ways. You can even use byte to represent an unsigned byte. You just need to perform a mapping in places that require it; e.g.
byte b = ...
int unsigned = (b >= 0) ? b : (b + 256);
... and that essentially they take up the same memory as an int.
That is also incorrect. It is true for a byte variable or field. However, the bytes in a byte array occupy 1/4 of the space of integers in an int array.
... is there really any difference when you send them over a packet?
Well yes. A byte sent over the network (in the natural fashion) takes 1/4 of the number of bits as an int sent over the network. If you are sending an "8 bit quantity" as 32 bits, then you are wasting network bandwidth.

How does signed byte sent from java application will arrive on arduino expecting unsigned byte?

My simple java application sends two bytes to arduino over bluetooth. One byte 0x0A and second byte will be 0xA0, or 0xA1, or 0xB0, or 0xB1...
Here is how two bytes are sent from java
public static byte RELAY_ACCESSORIES_OFF = (byte)0xB0;
public static byte RELAY_ACCESSORIES_ON = (byte)0xB1;
...
connection.Send(new byte[] {0x0A, RELAY_ACCESSORIES_ON});
else
connection.Send(new byte[] {0x0A, RELAY_ACCESSORIES_OFF});
And arduino just reads incoming data as a unsigned byte.
So how does this signed and unsigned byte work out between java and arduino?
Usigned and signed integer values (of the same size) are represented by the same bit patterns, the only difference lies in their interpretation. There is no such thing as a signed or unsigned byte when you reduce it to the pure binary representation.
A signed byte from a java can be transmitted just fine to a receiver that treats it as unsigned. Problem only commonly arise because the programmer is not aware of the very different behavior achieved depening on signed/unsigned when a byte its cast to a larger type (which is common in java to happen implicitly in practically any operation you can perform on a byte, since java operators like +, -, *, == are defined to operate alaways on the 32-bit sign extended value of a byte).

Categories

Resources