On paper, binary arithmetic is simple, but as a beginning programmer, I'm finding it a little difficult to come up with algorithms for the addition, subtraction, multiplication and division of binary numbers.
I have two binary numbers stored as strings, assume that any leading zeroes have been dropped. How would I go about performing these operations on the two numbers?
Edit: I need to avoid converting them to an int or long.
Binary string to int:
int i = Integer.parseInt("10101011", 2);
int j = Integer.parseInt("00010", 2);
Then you can do anything you please with the two ints, eg:
i = i + j;
i = i - j;
And to get them back to a binary string:
String s = Integer.toBinaryString(i);
The algorithms, from wikipedia:
Addition:
The simplest arithmetic operation in
binary is addition. Adding two
single-digit binary numbers is
relatively simple, using a form of
carrying:
0 + 0 → 0
0 + 1 → 1
1 + 0 → 1
1 + 1 → 0, carry 1 (since 1 + 1 = 0 + 1 × 10 in binary)
Adding two "1" digits produces a digit
"0", while 1 will have to be added to
the next column.
Subtraction:
Subtraction works in much the same
way:
0 − 0 → 0
0 − 1 → 1, borrow 1
1 − 0 → 1
1 − 1 → 0
Subtracting a "1" digit from a "0"
digit produces the digit "1", while 1
will have to be subtracted from the
next column. This is known as
borrowing. The principle is the same
as for carrying. When the result of a
subtraction is less than 0, the least
possible value of a digit, the
procedure is to "borrow" the deficit
divided by the radix (that is, 10/10)
from the left, subtracting it from the
next positional value.
Multiplication:
Multiplication in binary is similar to
its decimal counterpart. Two numbers A
and B can be multiplied by partial
products: for each digit in B, the
product of that digit in A is
calculated and written on a new line,
shifted leftward so that its rightmost
digit lines up with the digit in B
that was used. The sum of all these
partial products gives the final
result.
Since there are only two digits in
binary, there are only two possible
outcomes of each partial
multiplication:
* If the digit in B is 0, the partial product is also 0
* If the digit in B is 1, the partial product is equal to A
For example, the binary numbers 1011
and 1010 are multiplied as follows:
1 0 1 1 (A)
× 1 0 1 0 (B)
---------
0 0 0 0 ← Corresponds to a zero in B
+ 1 0 1 1 ← Corresponds to a one in B
+ 0 0 0 0
+ 1 0 1 1
---------------
= 1 1 0 1 1 1 0
The following code implements binary addition without actually doing any arithmetic, binary or otherwise. The actual "addition" is done by lookupTable, and everything else is straight-up string manipulation. I wrote it with the intention of making it as instructive as possible, emphasizing the process instead of efficiency. Hope it helps.
public class BinaryArithmetic {
static String[] lookupTable = {
"0+0+0=00",
"0+0+1=01",
"0+1+0=01",
"0+1+1=10",
"1+0+0=01",
"1+0+1=10",
"1+1+0=10",
"1+1+1=11",
};
static String lookup(char b1, char b2, char c) {
String formula = String.format("%c+%c+%c=", b1, b2, c);
for (String s : lookupTable) {
if (s.startsWith(formula)) {
return s.substring(s.indexOf("=") + 1);
}
}
throw new IllegalArgumentException();
}
static String zeroPad(String s, int length) {
while (s.length() < length) {
s = "0" + s;
}
return s;
}
static String add(String s1, String s2) {
int length = Math.max(s1.length(), s2.length());
s1 = zeroPad(s1, length);
s2 = zeroPad(s2, length);
String result = "";
char carry = '0';
for (int i = length - 1; i >= 0; i--) {
String columnResult = lookup(s1.charAt(i), s2.charAt(i), carry);
result = columnResult.charAt(1) + result;
carry = columnResult.charAt(0);
}
if (carry == '1') {
result = carry + result;
}
return result;
}
public static void main(String args[]) {
System.out.println(add("11101", "1001"));
}
}
While we're at it, I might as well do multiply too.
static String multiply(String s1, String s2) {
String result = "";
String zeroSuffix = "";
for (int i = s2.length() - 1; i >= 0; i--) {
if (s2.charAt(i) == '1') {
result = add(result, s1 + zeroSuffix);
}
zeroSuffix += "0";
}
return result;
}
Working with binary arithmetic is really no different than the more familiar base 10. Let's take addition for example
(1) (1)
182 182 182 182 182
845 845 845 845 845
--- + --- + --- + --- + --- +
7 27 027 1027
So what did you do? You right-align the numbers to add, and you proceed right-to-left, adding one digit at a time, carrying over +1 to the left as necessary.
In binary, the process is exactly the same. In fact, it's even simpler because you only have 2 "digits" now, 0 and 1!
(1) (1) (1)
11101 11101 11101 11101 11101 11101 11101
1001 1001 1001 1001 1001 1001 1001
----- + ----- + ----- + ----- + ----- + ----- + ----- +
0 10 110 0110 00110 100110
The rest of the operations work similarly too: the same process that you use for base 10, works for base 2. And again, it's actually simpler because there are only 2 "digits", 0 and 1. This simplicity is why hardware likes the binary system.
Convert the binary strings to Integers and then operate on the Integers, e.g.
String add(String s1, String s2) {
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
return Integer.toBinaryString(i1 + i2);
}
The built-in BitSet class is very straight-forward to use for bit-level operations.
Related
I'm trying to solve a problem, for the basic scenario it's working, nevertheless, I know that it is not optimal and has several faults.
Problem:
You are given a number n. Find the decimal value of the number formed by the concatenation of the binary representation of the first n positive integers. Print the answer 10^9 + 7.
Output format:
Print the answer modulo 10^9 + 7
Constraint:
1 <= n <= 10^9
Sample input: 3
Sample Output: 27
The binary representation of 1: 1
The binary representation of 2: 10
The binary representation of 3: 11
Concatenated string: 11011 -> Decimal representation is 27.
The first doubt that I have is: "modulo 10^9 + 7", I understand is the limit for the number of chars, but I don't know how to interpret it.
The second part of the question is with the solution:
Input: 20
Binary representation of 2 : 10.
Binary representation of 3 : 11
Binary representation of 4 : 100.
Binary representation of 5 : 101
Binary representation of 6 : 110
Binary representation of 7 : 111
Binary representation of 8 : 1000
Binary representation of 9 : 1001
Binary representation of 10 : 1010
Binary representation of 11 : 1011
Binary representation of 12 : 1100
Binary representation of 13 : 1101
Binary representation of 14 : 1110
Binary representation of 15 : 1111
Binary representation of 16 : 10000
Binary representation of 17 : 10001
Binary representation of 18 : 10010
Binary representation of 19 : 10011
The binary representation of 20: 10100
Concatenated string: 11011100101110111100010011010101111001101111011111000010001100101001110100
How would you recommend to tackle this kind of problem?
This is my current code:
public long FindBigNum(long n) {
System.out.println("");
System.out.println("Input: " + n);
StringBuilder binaryRepresentation = new StringBuilder();
for(Long i = 1l; i <= n; i++){
System.out.println("Binary representation of " + i + " : " + Long.toBinaryString(i));
binaryRepresentation.append(Long.toBinaryString(i));
}
System.out.println("Concatenated string: " + binaryRepresentation.toString());
//System.out.println("Binary representation: " + binaryRepresentation.toString());
long longRepresentation = parseLong(binaryRepresentation.toString(), 2);
//System.out.println("longRepresentation: " + l);
return longRepresentation;
}
public long parseLong(String s, int base){
return new BigInteger(s, base).longValue();
}
public class TestClass {
static long FindBigNum(long n) {
long result = 0;
StringBuilder binary = new StringBuilder();
long binarySumLong;
long moduloFactor = (long) (Math.pow(10, 9) + 7);
for (int number = 1; number < n; number++) {
System.out.println("Number is : " + number);
String binaryRepresentation = Long.toBinaryString(number);
System.out.println("Binary representation of " + number + " is " + binaryRepresentation);
binary.append(binaryRepresentation);
System.out.println("Value of StringBuffer binary is " + binary);
binarySumLong = binaryToInteger(binary.toString());
System.out.println("binarySumLong is : " + binarySumLong);
if (binarySumLong > (moduloFactor)) {
binarySumLong = binarySumLong % (moduloFactor);
binary = new StringBuilder(Long.toBinaryString(binarySumLong));
System.out.println(" *** binary after modification is : " + binary);
System.out.println(" *** and integer value of binary is : " + binaryToInteger(binary.toString()));
}
}
result = binaryToInteger(binary.toString());
return result;
}
public static int binaryToInteger(String binary) {
char[] numbers = binary.toCharArray();
int result = 0;
for (int i = numbers.length - 1; i >= 0; i--)
if (numbers[i] == '1')
result += Math.pow(2, (numbers.length - i - 1));
return result;
}
public static void main(String[] args) {
long output = FindBigNum((long) Math.pow(10, 4));
System.out.println("output is : " + output);
}
}
The first doubt that I have is: "modulo 10^9 + 7", I understand is the limit for the number of chars, but I don't know how to interpret it.
That means to get the remainder when dividing by that value. It is the value 1000000007 (I am assuming the caret is exponentiation).
Here is how I would approach this.
Generate your concatenated strings as you have been.
Use BigInteger to convert from binary to decimal and then take the mod with the BigInteger mod method.
That will ultimately be very slow and not efficient. However, it serves as a control to allow you to investigate optimal ways of doing it. Perhaps employing StringBuilder and pre-allocating storage for it. Writing your own int to binary conversion routine, etc.
It may even require more of a math solution (e.g. number theory) than a programming solution.
But you can compare your results to the BigInteger solution to verify if it is working.
I'm trying to solve the following problem from the section Bit Manipulation at the Hacker Rank site using new features of Java 8 such as Streams.
The problem description:
Given an integer, n, find each x such that:
0 <= x <= n
n + x = n ^ x
where ^ denotes the bitwise XOR operator. Then print an integer denoting the total number of x's satisfying the criteria above.
Constraints
0 <= n <= 1015
Sample Input: 5
Sample Output: 2
Explanation:
For n = 5, the x values 0 and 2 satisfy the conditions:
5 + 0 = 5 ^ 0 = 5
5 + 2 = 5 ^ 2 = 7
Thus, we print 2 as our answer.
Sample Input: 10
Sample Output: 4
Explanation:
For n = 10, the x values 0, 1, 4, and 5 satisfy the conditions:
10 + 0 = 10 ^ 0 = 10
10 + 1 = 10 ^ 1 = 11
10 + 4 = 10 ^ 4 = 14
10 + 5 = 10 ^ 5 = 15
Thus, we print 4 as our answer.
My code is as follows:
public class SumVsXor
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long count = LongStream.rangeClosed(0, n)
.filter(k -> k + n == (k ^ n))
.count();
System.out.println(count);
}
}
The problem is this code doesn't pass all the test cases.
It works for small values of n, but for large values such as 1000000000000000 it fails due to timeout.
I wonder whether LongStream can't handle Streams with that many elements.
The problem with your code is that it is very inefficient. For the case of n==1000000000000000, your Stream pipeline is performing 1,000,000,000,000,000 addition and XOR operations, which takes a long time. Testing for each number between 0 and n whether n + x == n ^ x would take a long time even if you use a for loop instead of Streams.
Instead of checking all the numbers between 0 and n, you should try to figure out a better way to calculate the required total number of x's. That fact that this problem appears under a "Bit Manipulation" section should give you a hint
to look into the bits of numbers that satisfy n + x == n ^ x.
Let's consider the case of n==1000000000000000. The binary representation of that large number is
0000000000000011100011010111111010100100110001101000000000000000
=== == = ====== = = = == == =
--- - - - - -- -- --- - ---------------
~~~~~~~~~~~~~~
In order for n + x to be equal to n ^ x, x must have a 0 value in all the bits corresponding with the 1 bits of n (marked with = above), and either 0 or 1 value in the bits corresponding with the 0 bits of n (marked with - above). This doesn't include the leading 0s (marked with ~ above), since x must be <= n, so any leading 0s in n must also have a 0 value in x.
This means that the total number of x's for which n + x == n ^ x is 2the number of 0s in n, not including leading 0s.
In the case of n = 1000000000000000, there are 30 such 0 bits, so the total number of x's that satisfy the requirement is 230.
Here's one way to compute the total number of x's :
long n = 1000000000000000L;
int zeroBitsCount = 0;
while (n > 0) {
if (n % 2 == 0) {
zeroBitsCount++; // counts the number of non-leading 0 bits
}
n = n >> 1; // divide n by 2 in order to examine the next bit in the next iteration
}
long total = 1L << zeroBitsCount; // the total is 2^(the 0 bits count)
I came to the same result, but via a different explanation, so thought I might post it here.
Eran's answer got to the same conclusion that I did : to modify the zeroes in the binary representation of the initial number - that is pretty straightforward.
Let's suppose our number is
101010100
so it has 5 zeroes.
you need all the possible combinations of:
a single zero
two zeroes
three zeroes
four zeroes
five zeroes
that is actually :
comb(1,5) + comb(2,5) + comb(3,5) + comb(4,5) + comb (5,5)
that is a well known formula being equal to:
pow(2,n) // where n is five in our case
from there the solution is obvious...
This is a simple question if you know little bit about XOR. I don't know much about java. But I can explain in python.
1.First convert the number to binary.
2.Count the number of zeros in that binary number.
3.print 2 ^ (number of zeros) and that's it.
Here is my python code.
n = int(input())
sum = 0
if n!=0:
n=str(bin(n))
for i in range(len(n)):
if n[i]=='0':
sum = sum + 1
print(2**(sum-1))
else: print(1)
The reason to decrement the sum by 1 is, in python it convert the number to the binary as this format. e.g: 0b'10101.
public static void main (String[] args) {
Scanner in = new Scanner (System.in);
long n = in.nextLong();
long count = 1L << (64-Long.bitCount(n)-Long.numberOfLeadingZeros(n));
System.out.println(count);
}
There is a changing rule that, 0 -> 01, 1 -> 10. For example, after the change, 10 is 1001.
Assume that the input is 0, after n changes of such rule, what is the Kth digit?
I can only come with the brutal solution, which is as followings. However I believe there exist better solutions, can anyone come up with some new ideas?
public char lalala(int n, int k) {
String str = "0";
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < str.length; j++) {
if (str.charAt(j) == '0') {
sb.append("01");
} else {
sb.append("10");
}
}
str = sb.toString();
}
return str.charAt(k);
}
So your generated string will look like
0110100110010110....
Now lets write this numbers vertically and lets print binary representation of position of each digit
value|position -> position binary
-----+---------------------------
0 | 0 -> 0000
1 | 1 -> 0001
1 | 2 -> 0010
0 | 3 -> 0011
1 | 4 -> 0100
0 | 5 -> 0101
0 | 6 -> 0110
1 | 7 -> 0111
. . ....
. . ....
If you take closer look you will see that:
if number of 1 in binary representation of position is even value is 0
if number of 1 in binary representation of position is odd value is 1
which means that
0001, 0010, 0100, 0111 contains odd number of 1 value will be 1.
In other words value is equal of number of ones modulo 2.
Using this fact you can create code which will convert your n to string representing its binary form, sum all ones, and check if it is odd or even.
Code converting n to value can look like this
public static int value(int n) {
String binary = Integer.toBinaryString(n);
return binary.chars().map(e -> e == '1' ? 1 : 0).sum() % 2;
}
(little longer version if you are not familiar with streams introduced in Java 8)
public static int value(Integer n) {
String binary = Integer.toBinaryString(n);
int count = 0;
for (char ch : binary.toCharArray())
if (ch == '1') count ++;
return count % 2;
}
and when you use it like
for (int i = 0; i < 20; i++)
System.out.print(value(i));
you will get as output 01101001100101101001 which seems correct.
For instance, How would I be able to convert 2^60 or 12345678901234567890123456789012345678901234567890 to binary?
Basically, numbers that are too large to represent in Java.
Edit: I will be making a class that will be able to represent number that are too large. I'm just having a hard time figuring our how to convert decimal to binary.
Edit2: And also, I am not allowed to use BigDecimal, BigInteger, or any other library, sorry for not specifying earlier.
Here is a quik&dirty (very very very dirty) code:
public class BigDec2Bin {
public static int[] string2arrayReversed( String s )
{
char a[] = s.toCharArray();
int b[] = new int[ s.length() ];
for( int i = 0; i < a.length; i++ )
{
b[a.length-1-i] = a[i] - 48;
}
return b;
}
// adds two binary numbers represented as strings
public static String add( String s1, String s2 )
{
String result = "", stmp;
int[] a1, a2;
int ctmp, mark = 0;
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() > s2.length() ? s1 : s2 ) );
a2 = string2arrayReversed( ( s1.length() < s2.length() ? s1 : s2 ) );
for( int i = 0; i < a1.length; i++ )
{
ctmp = a1[i] + ( i < a2.length ? a2[i] : 0 ) + mark;
switch( ctmp )
{
default:
case 0:
stmp = "0";
mark = 0;
break;
case 1:
stmp = "1";
mark = 0;
break;
case 2:
stmp = "0";
mark = 1;
break;
case 3:
stmp = "1";
mark = 1;
break;
}
result = stmp + result;
}
if( mark > 0 ) { result = "1" + result; }
return result;
}
public static String dec2bin( String s )
{
String result = "";
for( int i = 0; i < s.length() ; i++ )
{
result = add( result + "0", result + "000" );
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
}
return result;
}
public static void main( String[] args )
{
String dec = "12345"; // should be 11000000111001
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
dec = "12345678901234567890123456789012345678901234567890";
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
}
}
Output:
dec2bin( 12345 ) = 011000000111001
dec2bin(
12345678901234567890123456789012345678901234567890
) =
10000111001001111111011000110110100110101010111110000011110010100001010100000010011001110100011110101111100011000111111100011001011011001110001111110000101011010010
My main idea is to use always strings.
add -method adds two binary numbers which are represented as strings
dec2bin -method is where the magic happens.
Allow me to explain:
result = add( result + "0", result + "000" );
is a calculation to multiply any given number by 10.
Multiplying a binary number by 10 is the same as adding the number with shifts:
x*10 <=> x<<1 + x<<3
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
just adds a the next digit (from left to right) on the result string
Basicly what I'm doing is for example with 1234:
0*10 + 1 = 1
1*10 + 2 = 12
12*10 + 3 = 123
123*10 + 4 = 1234
but only in binary (represented as strings).
I hope i could help and sorry for my bad english.
Try this:
new BigDecimal("12345678901234567890123456789012345678901234567890").toString(2);
Edit:
For making a big-number class, you may want to have a look at my post about this a week ago. Ah, the question was by you, never mind.
The conversion between different number systems in principle is a repeated "division, remainder, multiply, add" operation. Let's look at an example:
We want to convert 123 from decimal to a base 3 number. What do we do?
Take the remainder modulo 3 - prepend this digit to the result.
Divide by 3.
If the number is bigger than 0, continue with this number at step 1
So it looks like this:
123 % 3 == 0. ==> The last digit is 0.
123 / 3 == 41.
41 % 3 == 2 ==> The second last digit is 2.
41 / 3 == 13
13 % 3 == 1 ==> The third digit is 1.
13 / 3 == 4
4 % 3 == 1 ==> The fourth digit is 1 again.
4 / 3 == 1
1 % 3 == 1 ==> The fifth digit is 1.
So, we have 11120 as the result.
The problem is that for this you need to have already some kind of division by 3 in decimal format, which is usually not the case if you don't implement your number in a decimal-based format (like I did in the answer to your last question linked above).
But it works for converting from your internal number format to any external format.
So, let's look at how we would do the inverse calculation, from 11120 (base 3) to its decimal equivalent. (Base 3 is here the placeholder for an arbitrary radix, Base 10 the placeholder for your internal radix.) In principle, this number can be written as this:
1 * 3^4 + 1 * 3^3 + 1*3^2 + 2*3^1 + 0*3^0
A better way (faster to calculate) is this:
((((1 * 3) + 1 )*3 + 1 )*3 + 2)*3 + 0
1
3
4
12
13
39
41
123
123
(This is known as Horner scheme, normally used for calculating values of polynomials.)
You can implement this in the number scheme you are implementing, if you know how to represent the input radix (and the digits) in your target system.
(I just added such a calculation to my DecimalBigInt class, but you may want to do the calculations directly in your internal data structure instead of creating a new object (or even two) of your BigNumber class for every decimal digit to be input.)
What about this approach:
result = 0;
for each digit in the decimal number, from left to right
result = result * 10 + digit;
return result;
So we need a way to represent an arbitrarily large binary number, and implement multiplication by 10 and addition of small numbers.
The most straightforward way to represent an arbitrarily large binary number is an array of its binary digits. You can then apply the algorithms for addition and multiplication your learned in elementary school, except that digits will "overflow" when they exceed 1 rather than 9. For example:
1010 * 1100111
----------------
11001110
+ 1100111000
----------------
10000000110
Pew: thanks, that works for some numbers. The number 6123456789012 however doesn't work, but here is the fix:
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() >= s2.length() ? s1 : s2 ) ); //GREATER EQUAL
If you only work with integers, use BigInteger.toByteArray.
If not, unfortunately BigDecimal doesn't have that method. But I suppose you can always (in both cases) just ASCII encode the string representation of the number, if the binary form is just meant for transfer and not calculation anywhere.
there is a fast program to get the binary representation of a huge decimal.
This programm is indeed fast, it takes only 20ms to deal with a decimal with 3000digits, eg:string(3000,'2')+'12345'. because of the pursuit of efficiency, it is not very readable. you can modify it yourself to make it easier to understand.
inline string remove_pre_zero(const string& a)
{
auto t = a.find_first_not_of('\0', 0);
if (t == a.npos)
return string("0");
else
return a.substr(t);
}
string convert_to_bin(const string& _s)
{
const static string str[] = { "0", "1" };
string s(_s.size(), '0');
string binary;
binary.reserve(_s.size()*3);
int i = 0;
for (const auto& c : _s)
s[i++] = (c - '0');
while (s!="0")//simulate divide by 2
{
int t = 0, old_t = 0;
for (auto& ch : s)
{
t = ((old_t * 10 + ch) & 1);
ch = (ch + old_t * 10) >>1;
old_t = t;
}
binary += str[t];
if (s[0] == 0)
s = remove_pre_zero(s);
}
return string(binary.rbegin(), binary.rend());
}
I'm trying to store a number as a binary string in an array but I need to specify how many bits to store it as.
For example, if I need to store 0 with two bits I need a string "00". Or 1010 with 6 bits so "001010".
Can anyone help?
EDIT: Thanks guys, as I'm rubbish at maths/programming in general I've gone with the simplest solution which was David's. Something like:
binaryString.append(Integer.toBinaryString(binaryNumber));
for(int n=binaryString.length(); n<numberOfBits; n++) {
binaryString.insert(0, "0");
}
It seems to work fine, so unless it's very inefficient I'll go with it.
Use Integer.toBinaryString() then check the string length and prepend it with as many zeros as you need to make your desired length.
Forget about home-made solutions. Use standard BigInteger instead. You can specify number of bits and then use toString(int radix) method to recover what you need (I assume you need radix=2).
EDIT: I would leave bit control to BigInteger. The object will internally resize its bit buffer to fit the new number dimension. Moreover arithmetic operations can be carried out by means of this object (you do not have to implement binary adders/multipliers etc.). Here is a basic example:
package test;
import java.math.BigInteger;
public class TestBigInteger
{
public static void main(String[] args)
{
String value = "1010";
BigInteger bi = new BigInteger(value,2);
// Arithmetic operations
System.out.println("Output: " + bi.toString(2));
bi = bi.add(bi); // 10 + 10
System.out.println("Output: " + bi.toString(2));
bi = bi.multiply(bi); // 20 * 20
System.out.println("Output: " + bi.toString(2));
/*
* Padded to the next event number of bits
*/
System.out.println("Padded Output: " + pad(bi.toString(2), bi.bitLength() + bi.bitLength() % 2));
}
static String pad(String s, int numDigits)
{
StringBuffer sb = new StringBuffer(s);
int numZeros = numDigits - s.length();
while(numZeros-- > 0) {
sb.insert(0, "0");
}
return sb.toString();
}
}
This is a common homework problem. There's a cool loop that you can write that will compute the smallest power of 2 >= your target number n.
Since it's a power of 2, the base 2 logarithm is the number of bits. But the Java math library only offers natural logarithm.
math.log( n ) / math.log(2.0)
is the number of bits.
Even simpler:
String binAddr = Integer.toBinaryString(Integer.parseInt(hexAddr, 16));
String.format("%032", new BigInteger(binAddr));
The idea here is to parse the string back in as a decimal number temporarily (one that just so happens to consist of all 1's and 0's) and then use String.format().
Note that you basically have to use BigInteger, because binary strings quickly overflow Integer and Long resulting in NumberFormatExceptions if you try to use Integer.fromString() or Long.fromString().
Try this:
String binaryString = String.format("%"+Integer.toString(size)+"s",Integer.toBinaryString(19)).replace(" ","0");
where size can be any number the user wants
Here's a simple solution for int values; it should be obvious how to extend it to e.g. byte, etc.
public static String bitString(int i, int len) {
len = Math.min(32, Math.max(len, 1));
char[] cs = new char[len];
for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) {
cs[j] = ((i & b) == 0) ? '0' : '1';
}
return new String(cs);
}
Here is the output from a set of sample test cases:
0 1 0 0
0 -1 0 0
0 40 00000000000000000000000000000000 00000000000000000000000000000000
13 1 1 1
13 2 01 01
13 3 101 101
13 4 1101 1101
13 5 01101 01101
-13 1 1 1
-13 2 11 11
-13 3 011 011
-13 4 0011 0011
-13 5 10011 10011
-13 -1 1 1
-13 40 11111111111111111111111111110011 11111111111111111111111111110011
Of course, you're on your own to make the length parameter adequate to represent the entire value.
import java.util.BitSet;
public class StringifyByte {
public static void main(String[] args) {
byte myByte = (byte) 0x00;
int length = 2;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
myByte = (byte) 0x0a;
length = 6;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
}
public static String stringifyByte(byte b, int len) {
StringBuffer bitStr = new StringBuffer(len);
BitSet bits = new BitSet(len);
for (int i = 0; i < len; i++)
{
bits.set (i, (b & 1) == 1);
if (bits.get(i)) bitStr.append("1"); else bitStr.append("0");
b >>= 1;
}
return reverseIt(bitStr.toString());
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
dest.append(source.charAt(i));
return dest.toString();
}
}
Output:
myByte: 0x0
bitString: 00
myByte: 0x10
bitString: 001010
So here instead of 8 you can write your desired length and it will append zeros accordingly. If the length of your mentioned integer exceeds that of the number mentioned then it will not append any zeros
String.format("%08d",1111);
Output:00001111
String.format("%02d",1111);
output:1111