Bit shifting exercise - java

The task is to read an integer from keyboard, convert it into 8 groups of 4 bits, then convert each bit into a hex number and output them one after one. This must be done by using bit shifting, no other solution counts.
My idea was to use a mask with 4 ones to select the group of bits, then shift that group right, removing preceding zeroes, and output the number in hex.
Here's how I tried to approach this:
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int x = input.nextInt();
System.out.println("Binary representation: " + Integer.toBinaryString(x));
System.out.println("Hexadecimal representatio1n: " + Integer.toHexString(x));
int mask = 15 << 28;
System.out.println(Integer.toBinaryString(mask));
int k = 28;
for (int i = 1; i <= 8; i++)
{
int result = mask & x;
//System.out.println(Integer.toBinaryString(result));
result = x >>> k ;
mask = mask >> 4;
k = k - 4;
System.out.println(Integer.toHexString(result));
}
}
Sample output:
Enter an integer: 324234234
Binary representation: 10011010100110110101111111010
Hexadecimal representatio1n: 13536bfa
11110000000000000000000000000000
1
13
135
1353
13536
13536b
13536bf
13536bfa
Why is it not working correctly?
Thanks.

Your when you shift the result variable, you aren't shifting by the result, you are shifting it by x
if you change it to
result = result >>> k;
it should work
on a side note, this problem is much easier done the other way(from the least significant bit to the most significant bit)
like
int x = 0xaabcdabcd;
int mask = 0x0fffffff;
for(int i =0;i < 8; i ++){
System.out.println(x & mask);
x = x >>> 4;
}

Because there are no unsigned types in Java, on line int mask = 15 << 28; you practically make your mask negative by moving bits up to sign field. Later you move it left with mask = mask >> 4; and thus carry down the sign bit. After the shift, your mask is not 00001111000000000000000000000000 but 11111111000000000000000000000000. Use logical right shift operator >>> instead.
PS. This seems like a homework. In such cases, one who asks question should mark the question with homework tag.

Related

What does '<< ' mean ? And what this code mean?

I don't understand what is this doCalculatePi means or does, in the following example:
public static double doCalculatePi(final int sliceNr) {
final int from = sliceNr * 10;
final int to = from + 10;
final int c = (to << 1) + 1;
double acc = 0;
for (int a = 4 - ((from & 1) << 3), b = (from << 1) + 1; b < c; a = -a, b += 2) {
acc += ((double) a) / b;
}
return acc;
}
public static void main(String args[]){
System.out.println(doCalculatePi(1));
System.out.println(doCalculatePi(2));
System.out.println(doCalculatePi(3));
System.out.println(doCalculatePi(4));
System.out.println(doCalculatePi(10));
System.out.println(doCalculatePi(100));
}
I have printed the values to understand what the results are but I still have no clue what this code calculates. The conditions inside the loop are not clear.
<< means left shift operation, which shifts the left-hand operand left by the number of bits specified by the right-hand operand (See oracle docs).
Say, you have a decimal value, 5 which binary representation is 101
Now for simplicity, consider,
byte a = (byte)0x05;
Hence, the bit representation of a will be,
a = 00000101 // 1 byte is 8 bit
Now if you left shift a by 2, then a will be
a << 2
a = 00010100 //shifted place filled with zero/s
So, you may now understand that, left shift a by 3 means
a << 3
a = 00101000
For better understanding you need to study Bitwise operation.
Note, you are using int instead of byte, and by default, the int data type is a 32-bit signed integer (reference here), so you have to consider,
int a = 5;
in binary
a << 3
a = 00000000 00000000 00000000 00101000 // total 32 bit
My guess is that it approximates PI with
PI = doCalculatePi(0)+doCalculatePi(1)+doCalculatePi(2)+...
Just a guess.
Trying this
double d = 0;
for(int k = 0; k<1000; k++) {
System.out.println(d += doCalculatePi(k));
}
gives me
3.0418396189294032
3.09162380666784
3.1082685666989476
[...]
3.1414924531892394
3.14149255348994
3.1414926535900394
<< is the Bitshift operator.
Basically, every number is represented as a series of binary digits (0's and 1's), and you're shifting each of those digits to the left by however many places you indicate. So for example, 15 is 00001111 and 15 << 1 is 00011110 (or 30), while 15 << 2 is (00111100) which is 60.
There's some special handling that comes into play when you get to the sign bit, but you should get the point.

Bit manipulation modify bits to include number

I am studying for an interview and I have been trying to understand this question for hours now:
You are given two 32-bit numbers, N and M, and two bit positions, i
and j. Write a method to set all bits between i and j in N equal to M
(e.g., M becomes a substring of N located at i and starting at j).
Could someone give a complete example and walk through what is actually required? Do i need to set the between i and j to form the value of M, or to actually the bits in M?
Is there some good tutorial on bits manipulation which explains the concepts?
Thank you!
Can be achieved using "masking"
creating a mask for the position i to j with each bit set to 1 using bitwise OR incrementally
blank out the bits in N using bitwise AND and bitwise NOT of the mask
select the bits from M using mask with bitwise AND
copy bits in using bitwise OR
I know I've used hex in my example, but same principle applies, just easier to read.
Example
int n = 0x12345678;
int m = 0x55555555;
int i = 4; // assume right to left
int j = 15;
int mask = 0;
for (int pos = i; pos <= j; pos++) {
mask = mask | (1 << pos);
}
System.out.println(String.format("mask is 0x%08x", mask));
int nCleared = n & ~mask;
System.out.println(String.format("clear n 0x%08x", nCleared));
int bitsFromM = (m & mask);
System.out.println(String.format("Bits from m 0x%08x", bitsFromM));
int nWithM = bitsFromM | nCleared;
System.out.println(String.format("n with m 0x%08x", nWithM));
Output
mask is 0x0000fff0
clear n 0x12340008
Bits from m 0x00005550
n with m 0x12345558
Let's say those 2 32-bit numbers are :-
M = "00010101010101010101010101010101";
N = "10101010100001010101100101011111";
i = 13;
j = 23;
They just want you to make N's 13th to 23rd bits the same as those in M.
I am counting the positions from the right-hand-side.
23rd bit 13th bit
So,here, M's 13th to 23rd character = "000101010_____ 10101010101 ___010101010101";
is the mid-spaced 10101010101.
Hence, N must be 101010101___ 10101010101 _____100101011111
or N = 101010101 "10101010101" 100101011111.

Get bits of a given range more effective?

It's been a while, that I did bit manipulations and I'm not sure if this can be done in a more effective way.
What I want is to get bits of a specific range from a value.
Let's say the binary of the value is: 0b1101101
Now I want to get a 4-bit range from the 2nd to the 5th bit of this value in it's two's complement.
The range I wanna get: 0b1011
Value in Two's complement: -5
This is the code I have, with some thoughts what I'm doing:
public int bitRange(int value, int from, int to) {
// cut the least significant bits
value = value >> from;
// create the mask
int mask = 0;
for (int i = from; i <= to; i++) {
mask = (mask << 1) + 1;
}
// extract the bits
value = value & mask;
// needed to check the MSB of the range
int msb = 1 << (to - from);
// if MSB is 1, XOR and inverse it
if ((value & msb) == msb ) {
value = value ^ mask;
value = ~value;
}
return value;
}
Now I would like to know if this can be done more effective? Especially the creation of the dynamic mask and the check of the MSB of the range, to be able to convert the bit range. Another point is, as user3344003 pointed out correctly, if the range would be 1 bit, the output would be -1. I'm sure there is a possible improvement.
For your mask, you could go something like
int mask = 0xffffffff >> 32-(to-from);
Though the chance of that exact code being correct is small. Probably off by one, edge issues, sign problems. But it's on the right track?
Here's your mask:
int mask = 0xffffffff >>> 32 - (to - from + 1);
You have to use >>> due to sign bit is 1.
Another solution could be to store the possible masks which can be 31 values at the most:
private static int[] MASKS = new int[31];
static {
MASKS[0] = 1;
for (int i = 1; i < MASKS.length; i++)
MASKS[i] = (MASKS[i - 1] << 1) + 1;
}
And using this your mask:
int mask = MASKS[to - from];
You can do the same for the msb mask, just store the possible values in a static array, and you don't have to calculate it in your method.
Disclaimer: I'm more of a C or C++ programmer, and I know there are some subtles between the bitwise operators in the different languages. But it seems to me that this can be done in one line as follows by taking advantage of the arithmetic shift that will result when shifting a negative value to the right, where one's will be shifted in for the sign extension.
public int bitRange(int value, int from, int to) {
int waste = 31 - to;
return (value << waste) >> (waste + from);
}
breakdown:
int a = 31 - to; // the number of bits to throw away on the left
int b = value << a; // shift the bits to throw away off the left of the value
int c = a + from; // the number of bits that now need to be thrown away on the right
int d = b >> c; // throw bits away on the right, and extend the sign on the left
return d;

Bitwise operator for simply flipping all bits in an integer?

I have to flip all bits in a binary representation of an integer. Given:
10101
The output should be
01010
What is the bitwise operator to accomplish this when used with an integer? For example, if I were writing a method like int flipBits(int n);, what would go in the body? I need to flip only what's already present in the number, not all 32 bits in the integer.
The ~ unary operator is bitwise negation. If you need fewer bits than what fits in an int then you'll need to mask it with & after the fact.
Simply use the bitwise not operator ~.
int flipBits(int n) {
return ~n;
}
To use the k least significant bits, convert it to the right mask.
(I assume you want at least 1 bit of course, that's why mask starts at 1)
int flipBits(int n, int k) {
int mask = 1;
for (int i = 1; i < k; ++i)
mask |= mask << 1;
return ~n & mask;
}
As suggested by Lưu Vĩnh Phúc, one can create the mask as (1 << k) - 1 instead of using a loop.
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return ~n & mask;
}
There is a number of ways to flip all the bit using operations
x = ~x; // has been mentioned and the most obvious solution.
x = -x - 1; or x = -1 * (x + 1);
x ^= -1; or x = x ^ ~0;
Well since so far there's only one solution that gives the "correct" result and that's.. really not a nice solution (using a string to count leading zeros? that'll haunt me in my dreams ;) )
So here we go with a nice clean solution that should work - haven't tested it thorough though, but you get the gist. Really, java not having an unsigned type is extremely annoying for this kind of problems, but it should be quite efficient nonetheless (and if I may say so MUCH more elegant than creating a string out of the number)
private static int invert(int x) {
if (x == 0) return 0; // edge case; otherwise returns -1 here
int nlz = nlz(x);
return ~x & (0xFFFFFFFF >>> nlz);
}
private static int nlz(int x) {
// Replace with whatever number leading zero algorithm you want - I can think
// of a whole list and this one here isn't that great (large immediates)
if (x < 0) return 0;
if (x == 0) return 32;
int n = 0;
if ((x & 0xFFFF0000) == 0) {
n += 16;
x <<= 16;
}
if ((x & 0xFF000000) == 0) {
n += 8;
x <<= 8;
}
if ((x & 0xF0000000) == 0) {
n += 4;
x <<= 4;
}
if ((x & 0xC0000000) == 0) {
n += 2;
x <<= 2;
}
if ((x & 0x80000000) == 0) {
n++;
}
return n;
}
faster and simpler solution :
/* inverts all bits of n, with a binary length of the return equal to the length of n
k is the number of bits in n, eg k=(int)Math.floor(Math.log(n)/Math.log(2))+1
if n is a BigInteger : k= n.bitLength();
*/
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return n ^ mask;
}
One Line Solution
int flippingBits(int n) {
return n ^ ((1 << 31) - 1);
}
I'd have to see some examples to be sure, but you may be getting unexpected values because of two's complement arithmetic. If the number has leading zeros (as it would in the case of 26), the ~ operator would flip these to make them leading ones - resulting in a negative number.
One possible workaround would be to use the Integer class:
int flipBits(int n){
String bitString = Integer.toBinaryString(n);
int i = 0;
while (bitString.charAt(i) != '1'){
i++;
}
bitString = bitString.substring(i, bitString.length());
for(i = 0; i < bitString.length(); i++){
if (bitString.charAt(i) == '0')
bitString.charAt(i) = '1';
else
bitString.charAt(i) = '0';
}
int result = 0, factor = 1;
for (int j = bitString.length()-1; j > -1; j--){
result += factor * bitString.charAt(j);
factor *= 2;
}
return result;
}
I don't have a java environment set up right now to test it on, but that's the general idea. Basically just convert the number to a string, cut off the leading zeros, flip the bits, and convert it back to a number. The Integer class may even have some way to parse a string into a binary number. I don't know if that's how the problem needs to be done, and it probably isn't the most efficient way to do it, but it would produce the correct result.
Edit: polygenlubricants' answer to this question may also be helpful
I have another way to solve this case,
public static int complementIt(int c){
return c ^ (int)(Math.pow(2, Math.ceil(Math.log(c)/Math.log(2))) -1);
}
It is using XOR to get the complement bit, to complement it we need to XOR the data with 1, for example :
101 XOR 111 = 010
(111 is the 'key', it generated by searching the 'n' square root of the data)
if you are using ~ (complement) the result will depend on its variable type, if you are using int then it will be process as 32bit.
As we are only required to flip the minimum bits required for the integer (say 50 is 110010 and when inverted, it becomes 001101 which is 13), we can invert individual bits one at a time from the LSB to MSB, and keep shifting the bits to the right and accordingly apply the power of 2. The code below does the required job:
int invertBits (int n) {
int pow2=1, int bit=0;
int newnum=0;
while(n>0) {
bit = (n & 1);
if(bit==0)
newnum+= pow2;
n=n>>1;
pow2*=2;
}
return newnum;
}
import java.math.BigInteger;
import java.util.Scanner;
public class CodeRace1 {
public static void main(String[] s) {
long input;
BigInteger num,bits = new BigInteger("4294967295");
Scanner sc = new Scanner(System.in);
input = sc.nextInt();
sc.nextLine();
while (input-- > 0) {
num = new BigInteger(sc.nextLine().trim());
System.out.println(num.xor(bits));
}
}
}
The implementation from openJDK, Integer.reverse():
public static int More ...reverse(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
Base on my experiments on my laptop, the implementation below was faster:
public static int reverse2(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i & 0x00ff00ff) << 8 | (i >>> 8) & 0x00ff00ff;
i = (i & 0x0000ffff) << 16 | (i >>> 16) & 0x0000ffff;
return i;
}
Not sure what's the reason behind it - as it may depends on how the java code is interpreted into machine code...
If you just want to flip the bits which are "used" in the integer, try this:
public int flipBits(int n) {
int mask = (Integer.highestOneBit(n) << 1) - 1;
return n ^ mask;
}
public static int findComplement(int num) {
return (~num & (Integer.highestOneBit(num) - 1));
}
int findComplement(int num) {
int i = 0, ans = 0;
while(num) {
if(not (num & 1)) {
ans += (1 << i);
}
i += 1;
num >>= 1;
}
return ans;
}
Binary 10101 == Decimal 21
Flipped Binary 01010 == Decimal 10
One liner (in Javascript - You could convert to your favorite programming language )
10 == ~21 & (1 << (Math.floor(Math.log2(21))+1)) - 1
Explanation:
10 == ~21 & mask
mask : For filtering out all the leading bits before the significant bits count (nBits - see below)
How to calculate the significant bit counts ?
Math.floor(Math.log2(21))+1 => Returns how many significant bits are there (nBits)
Ex:
0000000001 returns 1
0001000001 returns 7
0000010101 returns 5
(1 << nBits) - 1 => 1111111111.....nBits times = mask
It can be done by a simple way, just simply subtract the number from the value
obtained when all the bits are equal to 1 .
For example:
Number: Given Number
Value : A number with all bits set in a given number.
Flipped number = Value – Number.
Example :
Number = 23,
Binary form: 10111
After flipping digits number will be: 01000
Value: 11111 = 31
We can find the most significant set bit in O(1) time for a fixed size integer. For
example below code is for a 32-bit integer.
int setBitNumber(int n)
{
n |= n>>1;
n |= n>>2;
n |= n>>4;
n |= n>>8;
n |= n>>16;
n = n + 1;
return (n >> 1);
}

counting number of ones in binary representation of a number [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
I want to find out how many 1s are there in binary representation of a number.I have 2 logic .
int count =0;
int no = 4;
while(no!=0){
int d = no%2;
if(d==1)
count++;
no = no/2;
str = str+ d;
}
Now second logic is to keep on masking number iteratively with 1,2,4,8,32 and check if result is 1,2,4, 8..... Am not geting what should be ending condition for this loop.
Use Java API(java 5 or above).
Integer.bitCount(int);
Long.bitCount(long);
NOTE: The above java methods are based on hacker's delight
faster than any of the earlier answers:
(proportional to number of 1 bits rather than total bits)
public class Foo {
public static void main(String[] argv) throws Exception {
int no = 12345;
int count;
for (count = 0; no > 0; ++count) {
no &= no - 1;
}
System.out.println(count);
}
}
Looks like c/c++/c#, if so you have shifting.. just loop to N-1 bits from 0 and use sum+=(value>>i)&1
Ie: you always check the last/right most bit but move the binary representation of the number to the right for every iteration until you have no more bits to check.
Also, think about signed/unsigned and any integer format. But you dont state how that should be handled in the question.
We can make use of overflow for your loop:
int count = 0;
int number = 37;
int mask = 1;
while(mask!=0)
{
int d = number & mask;
if(d != 0)
count++;
/* Double mask until we overflow, which will result in mask = 0... */
mask = mask << 1;
str = str+ d;
}
One idea that's commonly employed for counting ones is to build a lookup table containing the answers for each individual byte, then to split apart your number into four bytes and sum the totals up. This requires four lookups and is quite fast. You can build this table by writing a program that manually computes the answer (perhaps using your above program), and then can write a function like this:
private static final int[] BYTE_TOTALS = /* ... generate this ... */;
public static int countOneBits(int value) {
return BYTE_TOTALS[value & 0xFF] +
BYTE_TOTALS[value >>> 8 & 0xFF] +
BYTE_TOTALS[value >>> 16 & 0xFF] +
BYTE_TOTALS[value >>> 24 & 0xFF];
}
Hope this helps!
There are various ways to do this very fast.
MIT HAKMEM Count
int no =1234;
int tmp =0;
tmp = no - ((no >> 1) & 033333333333) - ((no >> 2) & 011111111111);
System.out.println( ((tmp + (tmp >> 3)) & 030707070707) % 63);
Your end condition should be keeping track of the magnitude of the bit you are at; if it is larger than the original number you are done (will get only 0s from now on).
Oh, and since you didn't specify a language, here's a Ruby solution :)
class Integer
def count_binary_ones
to_s(2).scan('1').length
end
end
42.count_binary_ones #=> 3
How about using the BigInteger class.
public void function(int checkedNumber) {
BigInteger val = new BigInteger(String.valueOf(checkedNumber));
val = val.abs();
int count = val.bitCount();
String binaryString = val.toString(2);
System.out.println("count = " + count);
System.out.println("bin = " + binaryString);
}
The result of function(42); is following.
count = 3
bin = 101010

Categories

Resources