Java print four byte hexadecimal number - java

I have a small problem. I have numbers like 5421, -1 and 1. I need to print them in four bytes, like:
5421 -> 0x0000152D
-1 -> 0xFFFFFFFF
1 -> 0x00000001
Also, I have floating point numbers like 1.2, 58.654:
8.25f -> 0x41040000
8.26 -> 0x410428f6
0.7 -> 0x3f333333
I need convert both types of numbers into their hexadecimal version, but they must be exactly four bytes long (four pairs of hexadecimal digits).
Does anybody know how is this possible in Java? Please help.

Here are two functions, one for integer, one for float.
public static String hex(int n) {
// call toUpperCase() if that's required
return String.format("0x%8s", Integer.toHexString(n)).replace(' ', '0');
}
public static String hex(float f) {
// change the float to raw integer bits(according to the OP's requirement)
return hex(Float.floatToRawIntBits(f));
}

For Integers, there's an even easier way. Use capital 'X' if you want the alpha part of the hex number to be upper case, otherwise use 'x' for lowercase. The '0' in the formatter means keep leading zeroes.
public static String hex(int n)
{
return String.format("0x%04X", n);
}

Here it is for floats:
System.out.printf("0x%08X", Float.floatToRawIntBits(8.26f));

Use
String hex = Integer.toHexString(5421).toUpperCase(); // 152D
To get with leading zeroes
String hex = Integer.toHexString(0x10000 | 5421).substring(1).toUpperCase();

Related

Is there some sort of functionality in Java that converts a char into a bit?

I'm trying to find a way to convert a char (Precondition is the char can only be '0' or '1') into an actual bit in Java. I'm not sure if Java has some built-in functionality for this, or if there is an algorithm that can be implemented to do so.
I need to implement the following class:
public void writeBit(char bit) {
//PRE:bit == '0' || bit == '1'
try {
} catch (IOException e) {
System.out.println(e);
}
}
I cannot change the method structure in any way. I am implementing Huffman Encoding and have an array of Strings that represent the encodings for every character within an input file. For example, 'A' or array[65] contains the String: "01011". So if I see the letter A in my file, I need to use writeBit to write out A's respective String to a binary file. Every time I reach 8 bits (one byte) I will call writeByte to send those 8 bits to the binary file, then reset some sort of counter variable to 0 and continue.
What I'm stuck on is how I am supposed to convert the char bit into an actual bit, so that it can be properly written out to a binary file.
Java does not have a primitive data type representing a single bit. On many hardware architectures, it is not even possible to access memory with that granularity.
When you say "an actual bit", then, I can only assume that you mean an integer value that is either 0 or 1, as opposed to char values '0' and '1'. There are numerous ways to perform such a conversion, among them:
byte the_bit = bit - '0';. This takes advantage of the fact that char is an integer type, and that the decimal digits zero and one are encoded in Java with consecutive character codes.
byte the_bit = (bit == '0') ? 0 : 1;. This just explicitly tests whether bit contains the value '0', evaluating to 0 if so or 1 if not.
It gets more complicated from there, for example:
byte the_bit = Byte.parseByte(String.valueOf(bit));. This converts the char to a string containing (only) that char, and then parses it as the string representation of a byte.
All of the above rely to one degree or another on the precondition given: that bit does not have any value other than '0' or '1'.
With that said, I think anything like this is probably the wrong approach for implementing a Huffman encoding, because Java Strings are an unlikely, very heavyweight, representation for the bit strings involved.
You can use Integer.parseInt(String s, int radix) or Integer.parseUnsignedInt(String s, int radix) with radix 2, to convert from a "binary digits string" to internal int java integer form.
public static void main(String[] args) {
int num = Integer.parseInt("101010", 2);
// print 42
System.out.println(num);
}
And reversely with method Integer.toBinaryString(int i) you can generate the binary string representation:
// print 101010
System.out.println(Integer.toBinaryString(42));
Similarly you can use Byte.parseByte(String s, int radix) to parse a byte:
public static void main(String[] args) {
byte num = Byte.parseByte("101010", 2);
// print 42
System.out.println(num);
}

Long to hex String number of characters

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)

Hash a String into fixed bit hash value

I want to hash a word into fixed bit hash value say 64 bit,32 bit (binary).
I used the following code
long murmur_hash= MurmurHash.hash64(word);
Then murmur_hash value is converted into binary by the following function
public static String intToBinary (int n, int numOfBits) {
String binary = "";
for(int i = 0; i < numOfBits; ++i) {
n/=2;
if(n%2 == 0)
{
binary="0"+binary;
}
else
binary="1"+binary;
}
return binary;
}
Is there any direct hash method to convert into binary?
Just use this
Integer.toBinaryString(int i)
If you want to convert into a fixed binary string, that is, always get a 64-character long string with zero padding, then you have a couple of options. If you have Apache's StringUtils, you can use:
StringUtils.leftPad( Long.toBinaryString(murmurHash), Long.SIZE, "0" );
If you don't, you can write a padding method yourself:
public static String paddedBinaryFromLong( long val ) {
StringBuilder sb = new StringBuilder( Long.toBinaryString(val));
char[] zeros = new char[Long.SIZE - sb.length()];
Arrays.fill(zeros, '0');
sb.insert(0, zeros);
return sb.toString();
}
This method starts by using the Long.toBinaryString(long) method, which conveniently does the bit conversion for you. The only thing it doesn't do is pad on the left if the value is shorter than 64 characters.
The next step is to create an array of 0 characters with the missing zeros needed to pad to the left.
Finally, we insert that array of zeros at the beginning of our StringBuilder, and we have a 64-character, zero-padded bit string.
Note: there is a difference between using Long.toBinaryString(long) and Long.toString(long,radix). The difference is in negative numbers. In the first, you'll get the full, two's complement value of the number. In the second, you'll get the number with a minus sign:
System.out.println(Long.toString(-15L,2));
result:
-1111
System.out.println(Long.toBinaryString(-15L));
result:
1111111111111111111111111111111111111111111111111111111111110001
Another other way is using
Integer.toString(i, radix)
you can get string representation of the first argument i in the radix ( Binary - 2, Octal - 8, Decimal - 10, Hex - 16) specified by the second argument.

Converting a int to char and then back to int - doesn't give same result always

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

How Can I Convert Very Large Binary in String to Octal In Java

I have 1 String variable in my Java code and it contain of large binary digit. How can I convert it
String binary2 = JTextArea.gettext(); // this is a String variable
Long binary3 = Long.parseLong(binary2);
System.out.print(Long.toOctalString(binary3));
You can get use of BigInteger class which is more appropriate to use in your solution. It has an overloaded toString() method which takes radix (in your case radix = 8).
String largeBinary = "10101010100000100111011010101";
String octalVersion = (new BigInteger(largeBinary,2)).toString(8);
Every three binary digits (0 or 1) represent exactly one octal digit (from 0 to 7).
So I think the algorithm is simple: iterate over every 3 subsequent characters and convert them to one octal digit:
"000" -> "0"
"001" -> "1"
"010" -> "2"
"011" -> "3"
...
"111" -> "7"
Extra care need to be taken in the beginning if the length of the string is not a multiply of 3. Example:
"1001001110"
"10|101|001|110"
2| 5| 1| 6
This approach does not require parsing the string and no extra memory. It can work on arbitrarily long input and is super fast
A long value can hold any number up to 2^63-1, which is sufficient for many applications. All you need to do is to provide the appropriate radix parameter to the parseLong(String string, int radix) method (and the toString(Long number, int radix) method).
long number = Long.parseLong(binaryString, 2);
String octalString = Long.toOctalString(number); // or Long.toString(number, 8);

Categories