Hi i am trying to build a random 16 characters hex, to do so i tried a Long.toHexString(new Random().nextLong() my assumption is that it will always return a 16 chars string, Am i right ? (Once it returned 15 chars)
Take a look at the javadocs for toHexString(long i) (emphasis mine).
public static String toHexString(long i)
Returns a string
representation of the long argument as an unsigned integer in base 16.
The unsigned long value is the argument plus 264 if the argument is
negative; otherwise, it is equal to the argument. This value is
converted to a string of ASCII digits in hexadecimal (base 16) with no
extra leading 0s. If the unsigned magnitude is zero, it is represented
by a single zero character '0' ('\u0030'); otherwise, the first
character of the representation of the unsigned magnitude will not be
the zero character.
As it turns out, it will not always be 16 characters long. However you can pad with zeros if you want like so:
import java.util.Random;
class Main {
public static void main(String[] args) {
String hex16Chars = String.format("%016X", new Random().nextLong());
System.out.println(hex16Chars + ", len: " + hex16Chars.length());
}
}
You will see the length is always 16 as expected.
And it also turns out peeking at the docs actually helps! :)
Referring to Javadoc of the method in question should be your first port of call:
This value is converted to a string of ASCII digits in hexadecimal (base 16) with no extra leading 0s
So no, it won't always be 16 chars.
However, you can print a 16-char uppercased hex string, with leading zeros, using:
String.format("%016X", longValue)
Related
Hello here i want to convert Byte array ie 0x3eb to short so i considered 0x3eb as a string and tried to convert to short but its throwing Numberformat Exception...someone please help me
import java.io.UnsupportedEncodingException;
public class mmmain
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String ss="0x03eb";
Short value = Short.parseShort(ss);
System.out.println("value--->"+value);
}
}
Exception what im getting is
Exception in thread "main" java.lang.NumberFormatException:
For input string: "0x3eb" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:491)
at java.lang.Short.parseShort(Short.java:117)
at java.lang.Short.parseShort(Short.java:143)
at mmmain.main(mmmain.java:14)
even i tried converting 0x3eb to bytes by
byte[] bytes = ss.getBytes();
but i didnt found any implementation for parsing bytes to short.
Thanks in advance
See the doc of parseShort:
Parses the string argument as a signed decimal short. The characters
in the string must all be decimal digits, except that the first
character may be an ASCII minus sign '-' ('\u002D') to indicate a
negative value or an ASCII plus sign '+' ('\u002B') to indicate a
positive value.
The string to be parsed should only contain decimal characters and sign characters, it can not contains the 0x prefix.
Try:
String ss="3eb";
Short value = Short.parseShort(ss, 16);
Since the string value that you're using is a hexadecimal value, to convert it into short, you need to remove the 0x using a substring and pass the radix as below:
Short.parseShort(yourHexString.substring(2), 16)
Here 16 is the radix. More info in the doc here.
Update
Since the OP asked for some more clarification, adding the below info.
The short datatype can only have values between -32,768 and 32,767. It can't directly hold 0x3eb, but it can hold the equivalent decimal value of it. That's why when you parse it into the short variable and print, it shows 1003, which is the decimal equivalent of 0x3eb.
You have to cut "0x" from the beginning:
short.parseShort(yourHexString.Substring(2), 16)
Follow this document this may help you String to byte array, byte array to String in Java
I am trying to get a char from an int value > 0xFFFF. But instead, I always get back the same char value, that when cast to an int, prints the value 65535 (0xFFFF).
I couldn't understand why it is generating symbols for unicode > 0xFFFF.
int hex = 0x10FFFF;
char c = (char)hex;
System.out.println((int)c);
I expected the output to be 0x10FFFF. Instead, the output comes back as 65535.
This is because, while an int is 4 bytes, a char is only 2 bytes. Thus, you can't represent all values in a char that you can in an int. Using a standard unsigned integer representation, you can only represent the range of values from 0 to 2^16 - 1 == 65535 in a 2-byte value, so if you convert any number outside that range to a 2-byte value and back, you'll lose data.
int is 4 byte. char is 2 byte.
Your number was well within range an int can hold, but not which char can.
So when you converted that number to a char, it lost data and became the maximum a char can hold, which is what it printed i.e. 65535
Your number was too big to be a char which is 2 bytes. But it was small enough where it fit in as an int which is 4 bytes. 65535 is the biggest amount that fits in a char so that's why you got that value. Also, if a char was big enough to fit your number, when you returned it to an int it might have returned the decimal value for 0x10FFFF which is 1114111.
Unfortunately, I think you were expecting a Java char to be the same thing as a Unicode code point. They are not the same thing.
The Java char, as already expressed by other answers, can only support code points that can be represented in 16 bits, whereas Unicode needs 21 bits to support all code points.
In other words, a Java char on its own, only supports Basic Multilingual Plane characters (code points <= 0xFFFF). In Java, if you want to represent a Unicode code point that is in one of the extended planes (code points > 0xFFFF), then you need surrogate characters, or a pair of characters to do that. This is how UTF-16 works. And, internally, this is how Java strings work as well. Just for fun, run the following snippet to see how a single Unicode code point is actually represented by 2 characters if the code point is > 0xFFFF:
// Printing string length for a string with
// a single unicode code point: 0x22BED.
System.out.println("πΆ―".length()); // prints 2, because it uses a surrogate pair.
If you want to safely convert an int value that represents a Unicode code point to a char (or chars to be more exact), and then convert it back to an int code point, you will have to use code like this:
public static void main(String[] args) {
int hex = 0x10FFFF;
System.out.println(Character.isSupplementaryCodePoint(hex)); // prints true because hex > 0xFFFF
char[] surrogateChars = Character.toChars(hex);
int codePointConvertedBack = Character.codePointAt(surrogateChars, 0);
System.out.println(codePointConvertedBack); // prints 1114111
}
Alternatively, instead of manipulating char arrays, you can use a String, like this:
public static void main(String[] args) {
int hex = 0x10FFFF;
System.out.println(Character.isSupplementaryCodePoint(hex)); // prints true because hex > 0xFFFF
String s = new String(new int[] {hex}, 0, 1);
int codePointConvertedBack = s.codePointAt(0);
System.out.println(codePointConvertedBack); // prints 1114111
}
For further reading: Java Character Class
Why does this code throw a NumberFormatException :
String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// = 64
System.out.println(Long.parseLong(binStr, 2));
1000000000000000000000000000000000000000000000000000000000000000 is larger than Long.MAX_VALUE.
See https://stackoverflow.com/a/8888969/597657
Consider using BigInteger(String val, int radix) instead.
EDIT:
OK, this is new for me. It appears that Integer.parseInt(binaryIntegerString, 2) and Long.parseLong(binaryLongString, 2) parse binary as sign-magnitude not as a 2's-complement.
Because it's out of range. 1000...000 is 263, but Long only goes up to 263 - 1.
This is the same for all of Long, Integer, Short and Byte. I'll explain with a Byte example because it's readable:
System.out.println(Byte.MIN_VALUE); // -128
System.out.println(Byte.MAX_VALUE); // 127
String positive = "1000000"; // 8 binary digits, +128
String negative = "-1000000"; // 8 binary digits, -128
String plus = "+1000000"; // 8 binary digits, +128
Byte.parseByte(positive, 2); //will fail because it's bigger than Byte.MAX_VALUE
Byte.parseByte(negative, 2); //won't fail. It will return Byte.MIN_VALUE
Byte.parseByte(plus, 2); //will fail because its bigger than Byte.MAX_VALUE
The digits are interpreted unsigned, no matter what radix is provided. If you want a negative value, you have to have the minus sign at the beginning of the String. JavaDoc says:
Parses the string argument as a signed long in the radix specified by
the second argument. The characters in the string must all be digits
of the specified radix (as determined by whether Character.digit(char, int) returns a nonnegative value), except that the first character may
be an ASCII minus sign '-' ('\u002D') to indicate a negative value or
an ASCII plus sign '+' ('\u002B') to indicate a positive value. The
resulting long value is returned.
In order to get MAX_VALUE we need:
String max = "1111111"; // 7 binary digits, +127
// or
String max2 = "+1111111"; // 7 binary digits, +127
Largest long value is actually:
0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807
This is because Long.parseLong cannot parse two's complement representation. The only way to parse two's complement binary string representation in Java SE is BigInteger:
long l = new BigInteger("1000000000000000000000000000000000000000000000000000000000000000", 2).longValue()
this gives expected -9223372036854775808result
This is the largest possible long (9223372036854775807 = 2 exp 63 - 1) in binary format. Note the L at the end of the last digit.
long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;
Actually, this is works for me:
String bitStr = "-1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(Long.parseLong(bitStr, 2));
Here is a thing: inside Long.parseLong() code logic is looking for explicit sign first. And respectively to the sign, different limits are used (Long.MAX_VALUE for positive, and Long.MIN_VALUE for negative binary literals). Probably it would be better if this logic looked up first to the eldest bit (0 for positive and 1 for negative numbers) the sign
I am trying to parse the following String to Byte.But it gives me NumberFormat Exception.Can some body tell me what is the solution for this?
Byte.parseByte("11111111111111111111111110000001", 2);
Byte.parseByte() handles binary string as sign-magnitude not as a 2's complement, so the longest length you can have for a byte is 7 bits with a sign.
In other words, to represent -127, you should use:
Byte.parseByte("-111111", 2);
The following throws NumberFormatException:
Byte.parseByte("10000000", 2);
However, the binary literal of -127 is:
byte b = (byte) 0b10000000;
The same behavior is applied to the other parseXXX() methods.
Out of range of byte ie -128 to 127. From parseByte(String s,int radix) javadoc:
public static byte parseByte(String s, int radix)throws NumberFormatException
Parses the string argument as a signed byte in the radix specified by
the second argument. The characters in the string must all be digits,
of the specified radix (as determined by whether Character.digit(char,
int) returns a nonnegative value) except that the first character may
be an ASCII minus sign '-' ('\u002D') to indicate a negative value.
The resulting byte value is returned. An exception of type
NumberFormatException is thrown if any of the following situations
occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than
Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix,
except that the first character may be a minus sign '-' ('\u002D')
provided that the string is longer than length 1.
The value represented by the string is not a value of type byte.
Returns: the byte value represented by the string argument in the
specified radix Throws: NumberFormatException - If the string does not
contain a parsable byte.
from javadocs
An exception of type NumberFormatException is thrown if any of the
following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D')
provided that the string is longer than length 1.
The value represented by the string is not a value of type byte.
Your value is the second case that is out of range -128 to 127
Value is too large to be parsed in byte
Try this:
new BigInteger("011111111111111111111111110000001", 2).longValue();
i have code that looks like this
public static void main(String[] args) {
String string= "11011100010000010001000000000000";
String string1= "00000000010000110000100000101100";
System.out.println(Integer.toHexString(Integer.parseInt(string1,2)));
System.out.println(Integer.toHexString(Integer.parseInt(string,2)));
}
the first string convert just fine but the second one has an error of java.lang.NumberFormatException
dont know what the problem is
try this:
Long.toHexString(Long.parseLong(string,2))
(edited from parsLong to parseLong)
For what's worth, you can also use the BigInteger class :
String string = "11011100010000010001000000000000";
String string1 = "00000000010000110000100000101100";
System.out.println(new BigInteger(string1, 2).toString(16));
System.out.println(new BigInteger(string, 2).toString(16));
When the most significant bit of a 32-character binary number is set to 1, the resultant value exceeds the range of positive numbers supported by int, and can no longer be interpreted as a valid integer number. This causes the exception according to the documentation:
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') provided that the string is longer than length 1.
The value represented by the string is not a value of type int. (emphasis is mine)
In order to enter this negative binary value, use - sign in front of your number, and convert the remaining bits to 2-s complement representation.
If you need numbers that are longer than 32 bits, or if you would like the value to continue being interpreted as a positive number, you would need to switch to the 64-bit integer data type.
You can use Long instead of Integer, (Long.parseLong and Long.toHexString methods).
If you want to parse to integer, the range should be
10000000000000000000000000000000 to 01111111111111111111111111111111