Java byte array contains negative numbers
Java doesn't have unsigned bytes; all bytes are treated as signed. That's all.
All that really matters is how you think of the bytes, since you rarely ever actually need to do comparisons on bytes. The only significant difference is that they print out as signed, as you've discovered.
If you like, you can use e.g. Guava's UnsignedBytes
utilities to view Java bytes as unsigned, but there's really not much practical difference.
Converting String to UTF-8 byte array returns a negative value in Java
Answering the specific question
Does that mean that my byte still contains negative values despite converting it to UTF-8?
Yes, absolutely. That's because byte
is signed in Java. A byte
value of -61 would be 195 as an unsigned value. You should expect to get bytes which aren't in the range 0-127 when you encode any non-ASCII text with UTF-8.
The fix is easy: just clamp the range to 0-255 with a bit mask:
frequencies[b & 0xff]++;
Addressing what you're attempting to do
This line:
String tekst = new String(result2, StandardCharsets.UTF_8);
... is only appropriate if result2
is genuinely UTF-8-encoded text. It's not appropriate if result2
is some arbitrary binary data such as an image, compressed data, or even text encoded in some other encoding.
If you want to preserve arbitrary binary data as a string, you should use something like Base64 or hex. Basically, you need to determine whether your data is inherently textual (in which case, you should use strings for as much of the time as possible, and use an appropriate Charset
to convert to binary where necessary) or inherently binary (in which case you should use bytes for as much of the time as possible, and use base64 or hex to convert to text where necessary).
This line:
byte[] orig = tekst.getBytes();
... is almost always a bad idea. It uses the platform-default encoding to convert a string to bytes. If you really, really want to use the platform-default encoding, I would make that explicit:
byte[] orig = tekst.getBytes(Charset.defaultCharset());
... but this is an extremely unusual requirement these days. It's almost always better to stick to UTF-8 everywhere.
Convert byte[] with negative value to String
You should encode your byte array using Base64.
If you use Java8, Base64 is already included in java.util package.
Try the following code:
public static void main(String args[]) throws IOException {
byte[] b = {-53, 54, -5, -89, -69, -126, -57, 36, 49, 114, -66, 67, 39, 18, 57, -40, 50, -113, 52, -113, 111, -65, -20, -127, -84, 90, -74, -47, 94, 23, 18, -36};
String encoded = Base64.getEncoder().encodeToString(b);
System.out.println(encoded);
}
Result:
yzb7p7uCxyQxcr5DJxI52DKPNI9vv+yBrFq20V4XEtw=
turn negative bytes in byte array to positive by adding 256 - java
You can't represent anything over 127 as a positive valued byte. So you would have to have an array of ints
to show
the value like you want. I use the word show
because it is important to realize that this is just a representation of the actual value for use by humans. It has no bearing on the intrinsic nature of the value.
byte b = 239;
System.out.println(b);
Prints
-17
I suspect you would want the unsigned value which can be printed like so.
byte b = -17;
System.out.println(Byte.toUnsignedInt(b));
Prints
239
Java byte array to int function giving negative number
3770910849
is higher than Integer.MAX_VALUE
. If you require a positive value, use long instead of int.
For example :
static long byteArrayToInt(byte[] bytes) {
return (long)((bytes[0] << 24) | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF)) & 0xffffffffL;
}
How to convert negative byte value to either short or integer?
If the original length from entry.getKey().length
is greater than 255
, then the actual length information is lost. However, if the original length was between 128
and 255
, then it can be retrieved.
The narrowing conversion of casting to byte
keeps only the least significant 8 bits, but the 8th bit is now interpreted as -128
instead of 128
.
You can perform a bit-and operation with 0xFF
, which will retain all bits, but that implicitly widens the value back to an int
.
int length = lengthOfKey & 0xFF;
lengthOfKey (byte = -74): 10110110
Widening it to an int
, with sign extension:
lengthOfKey (int = -74): 11111111 11111111 11111111 10110110
Masking out the last 8 bits as an int
:
length (int = 182): 00000000 00000000 00000000 10110110
That will convert a negative byte
back to a number between 128
and 255
.
Related Topics
How to Determine the Primitive Type of a Primitive Variable
How to Give System Property to My Test via Gradle and -D
Differencebetween Synchronized on Lockobject and Using This as the Lock
Java: How to Use Urlconnection to Post Request with Authorization
How to Fix Invalid Byte 1 of 1-Byte Utf-8 Sequence
Java Native Method Source Code
Why Does My Aes Encryption Throws an Invalidkeyexception
Why Can't You Reduce the Visibility of a Method in a Java Subclass
Rejectedexecutionexception Inside Single Executor Service
Why String.Replaceall() in Java Requires 4 Slashes "\\\\" in Regex to Actually Replace "\"
Extended Server_Name (Sni Extension) Not Sent with Jdk1.8.0 But Send with Jdk1.7.0
Why Catch Exceptions in Java, When You Can Catch Throwables
Java String Array: Is There a Size of Method
Case Insensitive JSON to Pojo Mapping Without Changing the Pojo
Reading a Specific Line from a Text File in Java
Calling Base Class Overridden Function from Base Class Method