Given two integers a and b, how can we check that b is a rotated version of a?
For example if I have a = 0x01020304 (in binary 0000 0001 0000 0010 0000 0011 0000 0100), then the following b values are correct:
...
0x4080C1 (right-rotated by 2)
0x810182 (right-rotated by 1)
0x2040608 (left-rotated by 1)
0x4080C10 (left-rotated by 2)
...
For n bit numbers you can use KMP algorithm to search b inside two copies of a with complexity O(n).
In C++, without string conversion and assuming 32 bits int:
void test(unsigned a, unsigned b)
{
unsigned long long aa = a | ((unsigned long long)a<<32);
while(aa>=b)
{
if (unsigned(aa) == b) return true;
aa>>=1;
}
return false;
}
i think you have to do it in a loop (c++):
// rotate function
inline int rot(int x, int rot) {
return (x >> rot) | (x << sizeof(int)*8 - rot));
}
int a = 0x01020304;
int b = 0x4080C1;
bool result = false;
for( int i=0; i < sizeof(int)*8 && !result; i++) if(a == rot(b,i)) result = true;
In the general case (assuming arbitrary-length integers), the naive solution of consisting each rotation is O(n^2).
But what you're effectively doing is a correlation. And you can do a correlation in O(n log n) time by going via the frequency domain using an FFT.
This won't help much for length-32 integers though.
By deriving the answers here, the following method (written in C#, but shall be similar in Java) shall do the checking:
public static int checkBitRotation(int a, int b) {
string strA = Convert.ToString(a, 2).PadLeft(32, '0');
string strB = Convert.ToString(b, 2).PadLeft(32, '0');
return (strA + strA).IndexOf(strB);
}
If the return value is -1, b is not rotated version of a. Otherwise, b is rotated version of a.
If a or b is a constant (or loop-constant), you can precompute all rotations and sort them, and then do a binary search with the one that isn't a constant as key. That's fewer steps, but the steps are slower in practice (binary search is commonly implemented with a badly-predicted branch), so it might not be better.
In the case that it's really a constant, not a loop-constant, there are some more tricks:
if a is 0 or -1, it's trivial
if a has only 1 bit set, you can do the test like b != 0 && (b & (b - 1)) == 0
if a has 2 bits set, you can do the test like ror(b, tzcnt(b)) == ror(a, tzcnt(a))
if a has only one contiguous group of set bits, you can use
int x = ror(b, tzcnt(b));
int y = ror(x, tzcnt(~x));
const int a1 = ror(a, tzcnt(a)); // probably won't compile
const int a2 = ror(a1, tzcnt(~a1)); // but you get the idea
return y == a2;
if many rotations of a are the same, you may be able to use that to skip certain rotations instead of testing them all, for example if a == 0xAAAAAAAA, the test can be b == a || (b << 1) == a
you can compare to the smallest and biggest rotations of the constant for a quick pre-test, in addition to the popcnt test.
Of course, as I said in the beginning, none of this applies when a and b are both variables.
I would use Integer.rotateLeft or rotateRight func
static boolean isRotation(int a, int b) {
for(int i = 0; i < 32; i++) {
if (Integer.rotateLeft(a, i) == b) {
return true;
}
}
return false;
}
Related
I need to compare two integer using Bit operator.
I faced a problem where I have to compare two integers without using comparison operator.Using bit operator would help.But how?
Lets say
a = 4;
b = 5;
We have to show a is not equal to b.
But,I would like to extend it further ,say,we will show which is greater.Here b is greater..
You need at least comparison to 0 and notionally this is what the CPU does for a comparison. e.g.
Equals can be modelled as ^ as the bits have to be the same to return 0
(a ^ b) == 0
if this was C you could drop the == 0 as this can be implied with
!(a ^ b)
but in Java you can't convert an int to a boolean without at least some comparison.
For comparison you usually do a subtraction, though one which handles overflows.
(long) a - b > 0 // same as a > b
subtraction is the same as adding a negative and negative is the same as ~x+1 so you can do
(long) a + ~ (long) b + 1 > 0
to drop the +1 you can change this to
(long) a + ~ (long) b >= 0 // same as a > b
You could implement + as a series of bit by bit operations with >> << & | and ^ but I wouldn't inflict that on you.
You cannot convert 1 or 0 to bool without a comparison operator like Peter mentioned. It is still possible to get max without a comparison operator.
I'm using bit (1 or 0) instead of int to avoid confusion.
bit msb(x):
return lsb(x >> 31)
bit lsb(x):
return x &1
// returns 1 if x < 0, 0 if x >= 0
bit isNegative(x):
return msb(x)
With these helpers isGreater(a, b) looks like,
// BUG: bug due to overflow when a is -ve and b is +ve
// returns 1 if a > b, 0 if a <= b
bit isGreater_BUG(a, b):
return isNegative(b - a) // possible overflow
We need two helpers functions to detect same and different signs,
// toggles lsb only
bit toggle(x):
return lsb(~x)
// returns 1 if a, b have same signs (0 is considered +ve).
bit isSameSigns(a, b):
return toggle(isDiffSigns(a, b))
// returns 1 if a, b have different signs (0 is considered +ve).
bit isDiffSigns(a, b):
return msb(a ^ b)
So with the overflow issue fix,
// returns 1 if a > b, 0 if a <= b
bit isGreater(a, b):
return
(isSameSigns(a, b) & isNegative(b - a)) |
(isDiffSigns(a, b) & isNegative(b))
Note that isGreater works correctly for inputs 5, 0 and 0, -5 also.
It's trickier to implement isPositive(x) properly as 0 will also be considered positive. So instead of using isPositive(a - b) above, isNegative(b - a) is used as isNegative(x) works correctly for 0.
Now max can be implemented as,
// BUG: returns 0 when a == b instead of a (or b)
// returns a if a > b, b if b > a
int max_BUG(a, b):
return
isGreater(a, b) * a + // returns 0 when a = b
isGreater(b, a) * b //
To fix that, helper isZero(x) is used,
// returns 1 if x is 0, else 0
bit isZero(x):
// x | -x will have msb 1 for a non-zero integer
// and 0 for 0
return toggle(msb(x | -x))
So with the fix when a = b,
// returns 1 if a == b else 0
bit isEqual(a, b):
return isZero(a - b) // or isZero(a ^ b)
int max(a, b):
return
isGreater(a, b) * a + // a > b, so a
isGreater(b, a) * b + // b > a, so b
isEqual(a, b) * a // a = b, so a (or b)
That said, if isPositive(0) returns 1 then max(5, 5) will return 10 instead of 5. So a correct isPositive(x) implementation will be,
// returns 1 if x > 0, 0 if x <= 0
bit isPositive(x):
return isNotZero(x) & toggle(isNegative(x))
// returns 1 if x != 0, else 0
bit isNotZero(x):
return msb(x | -x)
Using binary two’s complement notation
int findMax( int x, int y)
{
int z = x - y;
int i = (z >> 31) & 0x1;
int max = x - i * z;
return max;
}
Reference: Here
a ^ b = c // XOR the inputs
// If a equals b, c is zero. Else c is some other value
c[0] | c[1] ... | c[n] = d // OR the bits
// If c equals zero, d equals zero. Else d equals 1
Note: a,b,c are n-bit integers and d is a bit
The solution in java without using a comparator operator:
int a = 10;
int b = 12;
boolean[] bol = new boolean[] {true};
try {
boolean c = bol[a ^ b];
System.out.println("The two integers are equal!");
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("The two integers are not equal!");
int z = a - b;
int i = (z >> 31) & 0x1;
System.out.println("The bigger integer is " + (a - i * z));
}
I am going to assume you need an integer (0 or 1) because you will need a comparison to get a boolean from integer in java.
Here, is a simple solution that doesn't use comparison but uses subtraction which can actually be done using bitwise operations (but not recommended because it takes a lot of cycles in software).
// For equality,
// 1. Perform r=a^b.
// If they are equal you get all bits 0. Otherwise some bits are 1.
// 2. Cast it to a larger datatype 0 to have an extra bit for sign.
// You will need to clear the high bits because of signed casting.
// You can split it into two parts if you can't cast.
// 3. Perform -r.
// If all bits are 0, you will get 0.
// If some bits are not 0, then you get a negative number.
// 4. Shift right to extract MSB.
// This will give -1 (because of sign extension) for not equal and 0 for equal.
// You can easily convert it to 0 and 1 by adding 1 (I didn't include it in below function).
int equality(int a, int b) {
long r = ((long)(a^b)) ^0xffffffffl;
return (int)(((long)-r) >> 63);
}
// For greater_than,
// 1. Cast a and b to larger datatype to get more bits.
// You can split it into two parts if you can't cast.
// 2. Perform b-a.
// If a>b, then negative number (MSB is 1)
// If a<=b, then positive number or zero (MSB is 0)
// 3. Shift right to extract MSB.
// This will give -1 (because of sign extension) for greater than and 0 for not.
// You can easily convert it to 0 and 1 by negating it (I didn't include it in below function).
int greater_than(int a, int b) {
long r = (long)b-(long)a;
return (int)(r >> 63);
}
Less than is similar to greater but you swap a and b.
Trivia: These comparison functions are actually used in security (Cryptography) because the CPU comparison is not constant-time; aka not secure against timing attacks.
So I have been trying to implement 2 functions:
Method to perform integer polynomial evaluation in O(d) time where d is the degree of the polynomial.
Calculate exponentiation. I'd need it to perform in 0(log b) time
Here is what I've come up so far:
public static int polynomialEvaluation(int[] coefficients, int x){
int n = coefficients.length -1;
int y = coefficients[n];
for (int i = n-1; i >= 0; i--){
y = coefficients[i] + (x*y);
}
return y;
}
public static int exponentiation(int a, int b) {
int res = 1;
while (b > 0) {
res = res * a;
b--;
}
return res;
}
}
Does any of those 2 meet the time complexity requirement? I think I had the exponent function but not sure the cost of the 1st one.
Edited: I rewrote exponential function trying avoid iteration loop as following. It might compute more efficiently now in my opinion
public static int exponentiation(int a, int b) {
if ( b == 0) return 1;
int res = exponentiation(a, b/2);
if (a % 2 == 0)
return res * res;
else
return (a * res * res);
}
Basic algebraic operations (such as addition and multiplication), array lookups, and assignments are all considered to take constant time. Since your code only consists of these operations in a loop, the complexity is the number of iterations of the loop (plus a constant for the operations outside, but that disappears in the O notation). How many iterations do each of your loops perform?
This will hopefully tell you that the polynomial calculation has the desired complexity while the exponential one does not. Hint for a better algorithm: If you have already computed b2, what is the fastest way to use that answer to compute b4? And if you have that result, how can you compute b8? If you have computed e.g. b2, b4, b8, b16, b32, and b64 in this manner (and, of course, you still have the original b1), how can you use these results to compute e.g. b93?
I want to implement a function to get the absolute value of a number in java: do nothing if it is positive, if it is negative, convert to positive.
I want to do this only using bit manipulations and no number comparators.
Please help
Well a negation:
-n
Is the same as the two's complement:
~n + 1
The problem is here you only want to negate if the value is < 0. You can find that out by using a logical shift to see if the MSB is set:
n >>> 31
A complement would be the same as an XOR with all 1's, something like (for a 4-bit integer):
~1010 == 1010 ^ 1111
And we can get a mask with the arithmetic right shift:
n >> 31
Absolute value says:
if n is < 0, negate it (take the complement and add 1 to it)
else, do nothing to it
So putting it together we can do the following:
static int abs(int n) {
return (n ^ (n >> 31)) + (n >>> 31);
}
Which computes:
if n is < 0, XOR it with all 1's and add 1 to it
else, XOR it with all 0's and add 0 to it
I'm not sure there's an easy way to do it without the addition. Addition involves any number of carries, even for a simple increment.
For example 2 + 1 has no carry:
10 + 1 == 11
But 47 + 1 has 4 carries:
101111 + 1 == 110000
Doing the add and carry with bitwise/bit shifts would basically just be a loop unroll and pointless.
(Edit!)
Just to be silly, here is an increment and carry:
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c;
do {
c = (n & s) << 1;
n ^= s;
} while((s = c) != 0);
return n;
}
The way it works is it flips the first bit, then keeps flipping until it finds a 0. So then the job is just to unroll the loop. The loop body can be represented by a somewhat ridiculous compound one-liner.
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c = (n & s) << 1;
c = ((n ^= s) & (s = c)) << 1; // repeat this line 30 more times
n ^= s;
return n;
}
So there's an abs using only bitwise and bit shifts.
These aren't faster than Math.abs. Math.abs just returns n < 0 ? -n : n which is trivial. And actually the loop unroll totally sucks in comparison. Just a curiosity I guess. Here's my benchmark:
Math.abs: 4.627323150634766ns
shift/xor/add abs: 6.729459762573242ns
loop abs: 12.028789520263672ns
unrolled abs: 32.47122764587402ns
bit hacks abs: 6.380939483642578ns
(The bit hacks abs is the non-patented one shown here which is basically the same idea as mine except a little harder to understand.)
you can turn a two's-compliment number positive or negative by taking it's logical negation
i = ~i; // i equals not i
You can use the Math.max() function to always get the positive
public static int abs(int i) {
return Math.max(i,~i);
}
This depends on what type of number you are using. For an int, use
int sign = i >> 31;
This gets the sign bit, which is 0 for positive numbers, and 1 for negative numbers. For other primitive types, replace 31 with the number of bits used for the primitive minus 1.
You can then use that sign in your if statement.
if (sign == 1)
i = ~i + 1;
I think you'll find that this little ditty is what you're looking for:
int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
It's based on Bit Twiddling Hacks absolute value equation and uses no comparison operations. If you aren't allowed to use addition, then (v ^ mask) - mask is an alternative. The value of this function is fairly questionable; since it's nearly as clear as the implementation of Math.abs and it's only marginally faster (at least on a i7):
v + mask ^ mask: 2.0844380704220384 abs/ns
(v ^ mask) - mask: 2.0819764093030244 abs/ns
Math.abs: 2.2636355843860656 abs/ns
Here's a test that proves that it works over the entire range of integers (the test runs in less than 2 minutes on an i7 processor under Java 7 update 51):
package test;
import org.hamcrest.core.Is;
import org.junit.Assert;
import org.junit.Test;
public class AbsTest {
#Test
public void test() {
long processedCount = 0L;
long numberOfIntegers = 1L << Integer.SIZE; //4294967296L
int value;
for (value = Integer.MIN_VALUE; processedCount < numberOfIntegers; value++) {
Assert.assertEquals((long) abs(value), (long) StrictMath.abs(value));
if (processedCount % 1_000_000L == 0L) {
System.out.print(".");
}
processedCount++;
}
System.out.println();
Assert.assertThat(processedCount, Is.is(numberOfIntegers));
Assert.assertThat(value - 1, Is.is(Integer.MAX_VALUE));
}
private static int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
}
This problem can be broken down into 2 simple steps:
1.
If >= 0 then just return the number.
2.
If smaller than 0 (ie. negative), then flip the first bit that indicates that the number is negative. This can easily be done with an XOR operation with -1 and the number; Then simply add +1 to deal with the offset (signed integers start at -1 not 0).
public static int absolute(int a) {
if (a >= 0) {
return a;
} else {
return (a ^ -1) + 1;
}
}
So if I have a number1 and another number2 .. both integers, is my approach corrected in adding two numbers using bitwise operations ? Can this go wrong for any test case ?
public int add(int number1, int number2)
{
int carry = (number1&number2)<<1;
int sum = number1^number2^carry;
return sum;
}
Here is how an circuit designer would add two numbers. To translate, the two symbols on top with the double curved left edges are XOR (^), the two in the middle with the flat left edges are AND (&), and the last one with the single curved left edge is OR (|).
Now, here's how you could translate that to code, one bit at a time, using a mask.
public int add(final int A, final int B) {
int mask = 1;
int sum = 0;
int carry = 0;
for (int i = 1; i <= Integer.SIZE; i++) { //JVM uses 32-bit int
int a = A & mask; //bit selection
int b = B & mask;
//sum uses |= to preserve the history,
//but carry does not need to, so it uses =
sum |= a ^ b ^ carry; //essentially, is the sum of bits odd?
carry = ((a & b) | ((a ^ b) & carry)) << 1; //are exactly two of them 1?
mask <<= 1; //move on to the next bit
}
return sum;
}
Yes. This approach does not work for additions that involve multiple carries. The simplest such case is 3 + 1; your function gives 0 as a result.
There is no simple general-case solution to solve this -- any solution must take into mind the width of an integer. See Wikipedia's article on gate-level implementations of addition for some approaches.
this is in JavaScript, but here goes.
function add(number1,number2){
var a = number1,b = number2,c;
while(b != 0){
c = a & b;
a = a ^ b;
b = c << 1;
}
return a;
}
here is an example
https://jsfiddle.net/Mythius/wum2huvu/4/
I was just going through the iterative version of fibonacci series algorithm. I found this following code
int Fibonacci(int n)
{
int f1 = 0;
int f2 = 1;
int fn;
for ( int i = 2; i < n; i++ )
{
fn = f1 + f2;
f1 = f2;
f2 = fn;
}
}
A silly question just raised in my mind. The function above adds two previous numbers and returns the third one and then get variables ready for the next iteration. What if it would be something like this. "Return a number of series which is the sum of previous three numbers" how we can change the above code to find such a number.u
As a hint, notice that the above algorithm works by "cycling" the numbers through some variables. In the above code, at each point you are storing
F_0 F_1
a b
You then "shift" them over by one step in the loop:
F_1 F_2
a b
You then "shift" them again in the next loop iteration:
F_2 F_3
a b
If you want to update the algorithm sum the last three values, think about storing them like this:
T_0 T_1 T_2
a b c
Then shift them again:
T_1 T_2 T_3
a b c
Then shift them again:
T_2 T_3 T_4
a b c
Converting this intuition into code is a good exercise, so I'll leave those details to you.
That said - there is a much, much faster way to compute the nth term of the Fibonacci and "Tribonacci" sequences. This article describes a very clever trick using matrix multiplication to compute terms more quickly than the above loop, and there is code available here that implements this algorithm.
Hope this helps!
I like recursion. Call me a sadist.
static int rTribonacci (int n, int a, int b, int c) {
if (n == 0) return a;
return rTribonacci (n-1, b, c, a + b + c);
}
int Tribonacci (int n) { return rTribonacci(n, 0, 0, 1); }
I don't normally answer questions that "smell" like homework, but since someone else already replied this is what I would do:
int Tribonacci(int n)
{
int last[3] = { 0, 0, 1 }; // the start of our sequence
for(int i = 3; i <= n; i++)
last[i % 3] = last[i % 3] + last[(i + 1) % 3] + last[(i + 2) % 3];
return last[n % 3];
}
It can be improved a bit to avoid all the ugly modular arithmetic (which I left in to make the circular nature of the last[] array clear) by changing the loop to this:
for(int i = 3; i <= n; i++)
last[i % 3] = last[0] + last[1] + last[2];
It can be optimized a bit more and frankly, there are much better ways to calculate such sequences, as templatetypedef said.
If you want to use recursion, you don't need any other parameters:
int FibonacciN(int position)
{ if(position<0) throw new ArgumentException("invalid position");
if(position==0 || position ==1) return position;
return FibonacciN(position-1) + FibonacciN(position-2);
}