Below is a snippet of my java code.
//converts a binary string to hexadecimal
public static String binaryToHex (String binaryNumber)
{
BigInteger temp = new BigInteger(binaryNumber, 2);
return temp.toString(16).toUpperCase();
}
If I input "0000 1001 0101 0111" (without the spaces) as my String binaryNumber, the return value is 957. But ideally what I want is 0957 instead of just 957. How do I make sure to pad with zeroes if hex number is not 4 digits?
Thanks.
You do one of the following:
Manually pad with zeroes
Use String.format()
Manually pad with zeroes
Since you want extra leading zeroes when shorter than 4 digits, use this:
BigInteger temp = new BigInteger(binaryNumber, 2);
String hex = temp.toString(16).toUpperCase();
if (hex.length() < 4)
hex = "000".substring(hex.length() - 1) + hex;
return hex;
Use String.format()
BigInteger temp = new BigInteger(binaryNumber, 2);
return String.format("%04X", temp);
Note, if you're only expecting the value to be 4 hex digits long, then a regular int can hold the value. No need to use BigInteger.
In Java 8, do it by parsing the binary input as an unsigned number:
int temp = Integer.parseUnsignedInt(binaryNumber, 2);
return String.format("%04X", temp);
The BigInteger becomes an internal machine representation of whatever value you passed in as a String in binary format. Therefore, the machine does not know how many leading zeros you would like in the output format. Unfortunately, the method toString in BigInteger does not allow any kind of formatting, so you would have to do it manually if you attempt to use the code you showed.
I customized your code a bit to include leading zeros based on input string:
public static void main(String[] args) {
System.out.println(binaryToHex("0000100101010111"));
}
public static String binaryToHex(String binaryNumber) {
BigInteger temp = new BigInteger(binaryNumber, 2);
String hexStr = temp.toString(16).toUpperCase();
int b16inLen = binaryNumber.length()/4;
int b16outLen = hexStr.length();
int b16padding = b16inLen - b16outLen;
for (int i=0; i<b16padding; i++) {
hexStr=('0'+hexStr);
}
return hexStr;
}
Notice that the above solution counts up the base16 digits in the input and calculates the difference with the base16 digits in the output. So, it requires the user to input a full '0000' to be counted up. That is '000 1111' will be displayed as 'F' while '0000 1111' as '0F'.
Related
I want to count set bits of binary number of any given number.
But the range of given number can vary to 10^200.
I tried using BigInteger and converted bigInteger to binary string using num.toString(2);
But maximum range of string is 2^31.
Any idea what else I can use here.
A BigInteger can be converted to a byte[] using BigInteger.toByteArray(). You can then iterate over the byte[] and count the set bits in each byte using code found here:
https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
Note that int can be replaced with byte in that example.
There's bitCount() method you can use for that:
// So, we create a big number
BigInteger num = new BigInteger("10");
num = num.pow(200);
System.out.println(num.bitCount());
Just for fun, you can test that it gives you the correct number:
String binaryNum = num.toString(2);
System.out.println(binaryNum);
System.out.println(binaryNum.chars().filter(c -> c == '1').count());
The maximum range of a String in Java is 2^31 - 1 is true but it's not about the Maximum value of a number it can hold, it is about the Number of characters it can contain.
That said, you don't need BigInteger to find the number of set bits in a number (Even for a large number), just remember the way to find Binary representation of a number.
Ex:
2|12|0
2| 6|0
2| 3|1
2| 1|-
So from the above, we know that the binary representation of 12 is 1100.
We can easily calculate the number of set bits if know the binary representation of a number.
Coming to the problem, you know that you can't handle that big into a number, so use a string to store the number and perform the above method.
To divide a number that is stored in a string start dividing the part of the number from the start,i.e., the most significant digit of the decimal number.
Check whether it propagates a carry to the right, you can do this by a simple &1 which tells about the LSB of those digits.
Finally, count the number of set bits with b.
public class Expelliarmus{
public static void main(String[] args) {
String a = "9000000000000000000000000000000000000000000000000000000000000000000000000000000000000";//88 zeroes, you can test it for other numbers too
System.out.println(fn(a,0L));
}
static long fn(String a, long b){ // Don't ask why I used long here
if(a.length()==0) return b;
if(a.length()==1 && a.charAt(0)=='1') return ++b;
int n = Integer.parseInt(a.charAt(a.length()-1)+"");
if((n&1)==1) ++b;
a = divideMe(a);
return fn(a,b);
}
static String divideMe(String a){
int val = 0;
String bb = "";
for(int i=0;i<a.length();i++){
int dup = 0;
val = val*10 + Integer.parseInt(a.charAt(i)+"");
if((val&1)==1) dup = 1;
val = val/2;
bb = bb + String.valueOf(val);
val = dup;
}
if(bb.charAt(0)=='0') return bb.substring(1);
return bb;
}
}
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.
The question has been answered for integers printed in decimal format, but I'm looking for an elegant way to do the same with integers in non-decimal format (like binary, octal, hex).
Creation of such Strings is easy:
String intAsString = Integer.toString(12345, 8);
would create a String with the octal represenation of the integer value 12345. But how to format it so that the String has like 10 digits, apart from calculating the number of zeros needed and assembling a new String 'by hand'.
A typical use case would be creating binary numbers with a fixed number of bits (like 16, 32, ...) where one would like to have all digits including leading zeros.
For oct and hex, it's as easy as String.format:
assert String.format("%03x", 16) == "010";
assert String.format("%03o", 8) == "010";
With Guava you could just write:
String intAsString = Strings.padStart(Integer.toString(12345, 8), 10, '0');
How about this (standard Java):
private final static String ZEROES = "0000000000";
// ...
String s = Integer.toString(12345, 8);
String intAsString = s.length() <= 10 ? ZEROES.substring(s.length()) + s : s;
Printing out a HEX number, for example, with ZERO padding:
System.out.println(String.format("%08x", 1234));
Will give the following output, with the padding included:
000004d2
Replacing x with OCTAL's associated formatting character will do the same, probably.
Here's a more reuseable alternative with help of StringBuilder.
public static String padZero(int number, int radix, int length) {
String string = Integer.toString(number, radix);
StringBuilder builder = new StringBuilder().append(String.format("%0" + length + "d", 0));
return builder.replace(length - string.length(), length, string).toString();
}
The Guava example as posted by ColinD is by the way pretty slick.
So I have a set of base digits like "BCDFGHJKLMNPQRSTVWXZ34679"
how do I convert a value say "D6CN96W6WT" to binary string in Java?
This should work (assuming 0,1 for you binary digits):
// your arbitrary digits
private static final String DIGITS = "BCDFGHJKLMNPQRSTVWXZ34679";
public String base25ToBinary(String base25Number) {
long value = 0;
char[] base25Digits = base25Number.toCharArray();
for (char digit : base25Digits) {
value = value * 25 + DIGITS.indexOf(digit);
}
return Long.toString(value, 2);
}
Off the top of my head, for base-25 strings.
Integer.toString(Integer.valueof(base25str, 25), 2)
Its a little unclear from your question whether you're talking about actual 0-9-Z bases, or a number encoding with an arbitrary list of symbols. I'm assuming the first, if its the later then you're out of luck on built-ins.
This question already has answers here:
How can I pad an integer with zeros on the left?
(18 answers)
Closed 8 years ago.
Is there a better way of getting this result? This function fails if num has more digits than digits, and I feel like it should be in the library somewhere (like Integer.toString(x,"%3d") or something)
static String intToString(int num, int digits) {
StringBuffer s = new StringBuffer(digits);
int zeroes = digits - (int) (Math.log(num) / Math.log(10)) - 1;
for (int i = 0; i < zeroes; i++) {
s.append(0);
}
return s.append(num).toString();
}
String.format (https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#syntax)
In your case it will be:
String formatted = String.format("%03d", num);
0 - to pad with zeros
3 - to set width to 3
Since Java 1.5 you can use the String.format method. For example, to do the same thing as your example:
String format = String.format("%0%d", digits);
String result = String.format(format, num);
return result;
In this case, you're creating the format string using the width specified in digits, then applying it directly to the number. The format for this example is converted as follows:
%% --> %
0 --> 0
%d --> <value of digits>
d --> d
So if digits is equal to 5, the format string becomes %05d which specifies an integer with a width of 5 printing leading zeroes. See the java docs for String.format for more information on the conversion specifiers.
Another option is to use DecimalFormat to format your numeric String. Here is one other way to do the job without having to use String.format if you are stuck in the pre 1.5 world:
static String intToString(int num, int digits) {
assert digits > 0 : "Invalid number of digits";
// create variable length array of zeros
char[] zeros = new char[digits];
Arrays.fill(zeros, '0');
// format number as String
DecimalFormat df = new DecimalFormat(String.valueOf(zeros));
return df.format(num);
}
How about just:
public static String intToString(int num, int digits) {
String output = Integer.toString(num);
while (output.length() < digits) output = "0" + output;
return output;
}
In case of your jdk version less than 1.5, following option can be used.
int iTest = 2;
StringBuffer sTest = new StringBuffer("000000"); //if the string size is 6
sTest.append(String.valueOf(iTest));
System.out.println(sTest.substring(sTest.length()-6, sTest.length()));