Fast way to find exponent of nearest superior power of 2 - java

If I have a number a, I want the value of x in b=2^x, where b is the next power of 2 greater than a.
In case you missed the tag, this is Java, and a is an int. I'm looking for the fastest way to do this. My solution thusfar is to use bit-twiddling to get b, then do (int)(log(b)/log(2)), but I feel like there has to be a faster method that doesn't involve dividing two floating-point numbers.

What about a == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(a - 1)? That avoids floating point entirely. If you know a is never 0, you can leave off the first part.

If anyone is looking for some "bit-twiddling" code that Andy mentions, that could look something like this: (if people have better ways, you should share!)
public static int nextPowerOf2(final int a)
{
int b = 1;
while (b < a)
{
b = b << 1;
}
return b;
}

Not necessarily faster, but one liner:
int nextPowerOf2(int num)
{
return num == 1 ? 1 : Integer.highestOneBit(num - 1) * 2;
}

If you need an answer that works for integers or floating point, both of these should work:
I would think that Math.floor(Math.log(a) * 1.4426950408889634073599246810019) + 1 would be your best bet if you don't want to do bit twiddling.
If you do want to bit-twiddle, you can use Double.doubleToLongBits(a) and then just extract the exponent. I'm thinking ((Double.doubleRawToLongBits(a) >>> 52) & 0x7ff) - 1022 should do the trick.

just do the following:
extract the highest bit by using this method (modified from hdcode):
int msb(int x) {
if (pow2(x)) return x;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x | (x >> 24);
return x - (x >> 1);
}
int pow2(int n) {
return (n) & (n-1) == 0;
}
combining both functions into this function to get a number 'b', that is the next power of 2 of a given number 'a':
int log2(int x) {
int pow = 0;
if(x >= (1 << 16)) { x >>= 16; pow += 16;}
if(x >= (1 << 8 )) { x >>= 8; pow += 8;}
if(x >= (1 << 4 )) { x >>= 4; pow += 4;}
if(x >= (1 << 2 )) { x >>= 2; pow += 2;}
if(x >= (1 << 1 )) { x >>= 1; pow += 1;}
return pow;
}
kind regards,
dave

How about divide-and-conquer? As in:
b = 0;
if (a >= 65536){a /= 65536; b += 16;}
if (a >= 256){a /= 256; b += 8;}
if (a >= 16){a /= 16; b += 4;}
if (a >= 4){a /= 4; b += 2;}
if (a >= 2){a /= 2; b += 1;}
Assuming a is unsigned, the divides should just be bit-shifts.
A binary IF-tree with 32 leaves should be even faster, getting the answer in 5 comparisons. Something like:
if (a >= (1<<0x10)){
if (a >= (1<<0x18)){
if (a >= (1<<0x1C)){
if (a >= (1<<0x1E)){
if (a >= (1<<0x1F)){
b = 0x1F;
} else {
b = 0x1E;
}
} else {
if (a >= (1<<0x1D)){
b = 0x1D;
} else {
b = 0x1C;
}
}
etc. etc.

Java provides a function that rounds down to the nearest power of 2. Thus a!=Integer.highestOneBit(a)?2*Integer.highestOneBit(a):a is a slightly prettier solution, assuming a is positive.
Storing Integer.highestOneBit(a) in a variable may further improve performance and readability.

To add to Jeremiah Willcock's answer, if you want the value of the power of 2 itself, then you will want:
(int) Math.pow(2, (a == 0) ? 0 : 32 - Integer.numberOfLeadingZeros(numWorkers));

Here is my code for the same. Will this be faster?
int a,b,x,y;
Scanner inp = new Scanner(System.in);
a = inp.nextInt();
y = (int) (Math.log(a)/Math.log(2));
x = y +1;
System.out.println(x);

Related

Left Shift Operator, Java : How does 0 / 2 doesn't throws error

I was looking into this video, for a really famous question for bit manipulation
He wrote this statement
count -= (1 << ((length - 1) / 2));
I am not able to understand.
Consider if I pass length as 1, why does this statement doesn't throws ArithmeticException
for 0 / 2.
I am missing out the core fundamental over here.
Please help me out here.
Here is the full code for reference:
public int solve(int A) {
if(A == 0)
return 0;
int result = 1;
int length = 1;
int count = 1;
while(count < A) {
length++;
count += (1 << ((length - 1) / 2));
}
count -= (1 << ((length - 1) / 2));
int offset = A - count - 1;
result |= (1 << (length - 1));
result |= offset << (length / 2);
int halfShiftedNumber = (result >> (length / 2));
int reversedNumber = getReversedNumber(halfShiftedNumber);
result |= reversedNumber;
return result;
}
int getReversedNumber(int A) {
int result = 0;
while(A > 0) {
int lsb = (A & 1);
result |= lsb;
result = result << 1;
A = A >> 1;
}
result = result >> 1;
return result;
}
What if I pass 1 as an input to the function.. it should throw ArithmeticException.
But its not..
Can anyone help me, explaining this basic stuff.
Thanks!
0 / NaturalNumber is a valid mathematical operation that will result a 0. So programming languages support the operation. (this applies to negative and floating point numbers too)
In the related context, 0 as denominator is undefined.
So, for AnyNumber / 0 operation, programming languages can throw exception.
Issues to consider
Please be aware that when length is zero or negative (so that length-1 is negative), then it will result in unexpected result.
In the context of integer, somenumber << -value is similar to somenumber << ((32 - value) % 32)
In the context of long, somenumber << -value is similar to somenumber << ((64 - value) % 64)

Is there any java built-in method to get parity of Integer?

I was working on Bit manipulation lessons. And I found the c++ built-in functions such as __builtin_clz(),__builtin_popcount(),__builtin_parity().
I got all alternative java methods for set bits and trailing zeroes. For parity, I didn't find any method.
I did something like this.
int val = 0b100011;
System.out.println(Integer.bitCount(val)%2==0?"Even":"ODD");
Is there any efficient way to do this?
There is no built in method to get the parity of an integer.
I'm not sure what you mean by efficient, but in terms of time complexity your solution is O(1).
Another solution is to use something like this which is also constant time complexity (taken from the link above, but also similar to the book Hacker's Delight):
static boolean hasEvenParity(int x)
{
int y = x ^ (x >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
y = y ^ (y >> 8);
y = y ^ (y >> 16);
// Rightmost bit of y holds the parity value
// if (y&1) is 1 then parity is odd else even
return (y & 1) == 0;
}
You can use the following method to find parity as there is no built-in function to do the same. A number is said to have odd parity if it contains odd number of 1s. Otherwise it is said to have even parity.
public static String findParity(int x){
boolean isOdd = false;
while(x != 0) {
isOdd = !isOdd;
x= x& (x-1);
}
return (isOdd)?"odd":"even";
}
You can also do it using a BitSet. And you can also pass in Strings.
int v = 292229202;
BitSet bs = BitSet.valueOf(new long[] { v
});
// number of bits set to 1.
System.out.println(bs.cardinality());
String s = "To be or not to be that is the question.";
BitSet bs1 = BitSet.valueOf(s.getBytes());
System.out.println(bs1.cardinality());
String parity = (bs1.cardinality() & 1) == 1 ? "odd" : "even";
And then there's the basic technique of iteration.
int sum = 0;
for (byte b : s.getBytes()) {
while (b != 0) {
sum += (b & 1);
b >>>= 1;
}
}
System.out.println((sum & 1) == 1 ? "odd"
: "even");

What is the most time efficient algorithm/code to reverse a very large integer?

I am trying to get the most efficient algorithm to reverse a large integer in Java.
E.g. if we have to reverse 301324354432.
Till now I have the below code:
public int reverse(int x) {
int result = 0;
while (x != 0)
{
int tail = x % 10;
int newResult = result * 10 + tail;
if ((newResult - tail) / 10 != result)
{ return 0; }
result = newResult;
x = x / 10;
}
return result;
}
What is the correct algorithm to achieve this at best time complexity?
An efficient way is to do it as shown below (similar to what you suggested).
public static long reverse(long x) {
long y = 0;
while(x > 0) {
y = y * 10 + x % 10;
x = x / 10;
}
return y;
}
This avoids expensive string conversions, does only one pass through the digits and does not use any memory (except for storing the result).
EDIT
A more efficient way, avoiding division and modulo operations is:
public static long reverse(int _x) {
long x = _x;
long y = 0;
while (x > 0) {
y = x + (y - ((x * 0x1999999Al) >> 32)) * 10; //y * 10 + x - (x/10) * 10;
x = ((x * 0x1999999Al) >> 32);
}
return y;
}
I also tried replacing multiplication by 10 using bitshift operations (x * 10 = (x << 3) + (x << 1)) but it didn't seem to affect performance.
The top answer of this stackoverflow question shows how to divide fast by 10. For completeness, the answer provided states that it can be done as follows (credit to John Källén)
int32_t div10(int32_t dividend) {
int64_t invDivisor = 0x1999999A;
return (int32_t) ((invDivisor * dividend) >> 32);
}
This approach only allows to reverse an integer number (up to 2^31 - 1). The result is a long, as 2^31 - 1 = 2147483647 and reverse(2147483647) = 7463847412 > 2^31 - 1.
A fast way to perform a modulo 10 operation on x is to divide and multiply it by 10, and then subtract that result from x.
public int reverse(int x) {
int result = 0;
StringBuffer sb = new StringBuffer(0);
sb.append(x);
result = Integer.parseInt(sb.reverse().toString());
return result;
}
You can take advantage of Java lambda expression. All you have to do is convert the number to String, use lambda to reverse it and then convert back to int. A little variation of this code can allow the reversal of any number of characters. Here:
public static int reversal(int x) {
String tmp = String.valueOf( x );
String result = Pattern.compile(" +").splitAsStream( tmp ).map(word->new StringBuilder(word).reverse())
.collect(Collectors.joining(" "));
return Integer.parseInt( result );
}

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);
}

How can I perform multiplication without the '*' operator?

I was just going through some basic stuff as I am learning C. I came upon a question to multiply a number by 7 without using the * operator. Basically it's like this
(x << 3) - x;
Now I know about basic bit manipulation operations, but I can't get how do you multiply a number by any other odd number without using the * operator? Is there a general algorithm for this?
Think about how you multiply in decimal using pencil and paper:
12
x 26
----
72
24
----
312
What does multiplication look like in binary?
0111
x 0101
-------
0111
0000
0111
-------
100011
Notice anything? Unlike multiplication in decimal, where you need to memorize the "times table," when multiplying in binary, you are always multiplying one of the terms by either 0 or 1 before writing it down in the list addends. There's no times table needed. If the digit of the second term is 1, you add in the first term. If it's 0, you don't. Also note how the addends are progressively shifted over to the left.
If you're unsure of this, do a few binary multiplications on paper. When you're done, convert the result back to decimal and see if it's correct. After you've done a few, I think you'll get the idea how binary multiplication can be implemented using shifts and adds.
Everyone is overlooking the obvious. No multiplication is involved:
10^(log10(A) + log10(B))
The question says:
multiply a number by 7 without using * operator
This doesn't use *:
number / (1 / 7)
Edit:
This compiles and works fine in C:
int number,result;
number = 8;
result = number / (1. / 7);
printf("result is %d\n",result);
An integer left shift is multiplying by 2, provided it doesn't overflow. Just add or subtract as appropriate once you get close.
int multiply(int multiplicand, int factor)
{
if (factor == 0) return 0;
int product = multiplicand;
for (int ii = 1; ii < abs(factor); ++ii) {
product += multiplicand;
}
return factor >= 0 ? product : -product;
}
You wanted multiplication without *, you got it, pal!
It's easy to avoid the '*' operator:
mov eax, 1234h
mov edx, 5678h
imul edx
No '*' in sight. Of course, if you wanted to get into the spirit of it, you could also use the trusty old shift and add algorithm:
mult proc
; Multiplies eax by ebx and places result in edx:ecx
xor ecx, ecx
xor edx, edx
mul1:
test ebx, 1
jz mul2
add ecx, eax
adc edx, 0
mul2:
shr ebx, 1
shl eax, 1
test ebx, ebx
jnz mul1
done:
ret
mult endp
Of course, with modern processors, all (?) have multiplication instructions, but back when the PDP-11 was shiny and new, code like this saw real use.
Mathematically speaking, multiplication distributes over addition. Essentially, this means:
x * (a + b + c ...) = (x * a) + (x * b) + (x * c) ...
Any real number (in your case 7), can be presented as a series of additions (such as 8 + (-1), since subtraction is really just addition going the wrong way). This allows you to represent any single multiplication statement as an equivalent series of multiplication statements, which will come up with the same result:
x * 7
= x * (8 + (-1))
= (x * 8) + (x * (-1))
= (x * 8) - (x * 1)
= (x * 8) - x
The bitwise shift operator essentially just multiplies or divides a number by a power of 2. So long as your equation is only dealing with such values, bit shifting can be used to replace all occurrence of the multiplication operator.
(x * 8) - x = (x * 23) - x = (x << 3) - x
A similar strategy can be used on any other integer, and it makes no difference whether it's odd or even.
It is the same as x*8-x = x*(8-1) = x*7
Any number, odd or even, can be expressed as a sum of powers of two. For example,
1 2 4 8
------------------
1 = 1
2 = 0 + 2
3 = 1 + 2
4 = 0 + 0 + 4
5 = 1 + 0 + 4
6 = 0 + 2 + 4
7 = 1 + 2 + 4
8 = 0 + 0 + 0 + 8
11 = 1 + 2 + 0 + 8
So, you can multiply x by any number by performing the right set of shifts and adds.
1x = x
2x = 0 + x<<1
3x = x + x<<1
4x = 0 + 0 + x<<2
5x = x + 0 + x<<2
11x = x + x<<1 + 0 + x<<3
When it comes down to it, multiplication by a positive integer can be done like this:
int multiply(int a, int b) {
int ret = 0;
for (int i=0; i<b; i++) {
ret += b;
}
return ret;
}
Efficient? Hardly. But it's correct (factoring in limits on ints and so forth).
So using a left-shift is just a shortcut for multiplying by 2. But once you get to the highest power-of-2 under b you just add a the necessary number of times, so:
int multiply(int a, int b) {
int ret = a;
int mult = 1;
while (mult <= b) {
ret <<= 1;
mult <<= 1;
}
while (mult < b) {
ret += a;
}
return ret;
}
or something close to that.
To put it another way, to multiply by 7.
Left shift by 2 (times 4). Left shift 3 is 8 which is >7;
Add b 3 times.
One evening, I found that I was extremely bored, and cooked this up:
#include <iostream>
typedef unsigned int uint32;
uint32 add(uint32 a, uint32 b) {
do {
uint32 s = a ^ b;
uint32 c = a & b;
a = s;
b = c << 1;
} while (a & b)
return (a | b)
}
uint32 mul(uint32 a, uint32 b) {
uint32 total = 0;
do {
uint32 s1 = a & (-(b & 1))
b >>= 1; a <<= 1;
total = add(s1, total)
} while (b)
return total;
}
int main(void) {
using namespace std;
uint32 a, b;
cout << "Enter two numbers to be multiplied: ";
cin >> a >> b;
cout << "Total: " << mul(a,b) << endl;
return 0;
}
The code above should be quite self-explanatory, as I tried to keep it as simple as possible. It should work, more or less, the way a CPU might perform these operations. The only bug I'm aware of is that a is not permitted to be greater than 32,767 and b is not permitted to be large enough to overflow a (that is, multiply overflow is not handled, so 64-bit results are not possible). It should even work with negative numbers, provided the inputs are appropriately reinterpret_cast<>.
O(log(b)) method
public int multiply_optimal(int a, int b) {
if (a == 0 || b == 0)
return 0;
if (b == 1)
return a;
if ((b & 1) == 0)
return multiply_optimal(a + a, b >> 1);
else
return a + multiply_optimal(a + a, b >> 1);
}
The resursive code works as follows:
Base case:
if either of the number is 0 ,product is 0.
if b=1, product =a.
If b is even:
ab can be written as 2a(b/2)
2a(b/2)=(a+a)(b/2)=(a+a)(b>>1) where'>>' arithematic right shift operator in java.
If b is odd:
ab can be written as a+a(b-1)
a+a(b-1)=a+2a(b-1)/2=a+(a+a)(b-1)/2=a+(a+a)((b-1)>>1)
Since b is odd (b-1)/2=b/2=b>>1
So ab=a+(2a*(b>>1))
NOTE:each recursive call b is halved => O(log(b))
unsigned int Multiply(unsigned int m1, unsigned int m2)
{
unsigned int numBits = sizeof(unsigned int) * 8; // Not part of the core algorithm
unsigned int product = 0;
unsigned int mask = 1;
for(int i =0; i < numBits; ++i, mask = mask << 1)
{
if(m1 & mask)
{
product += (m2 << i);
}
}
return product;
}
#Wang, that's a good generalization. But here is a slightly faster version. But it assumes no overflow and a is non-negative.
int mult(int a, int b){
int p=1;
int rv=0;
for(int i=0; a >= p && i < 31; i++){
if(a & p){
rv += b;
}
p = p << 1;
b = b << 1;
}
return rv;
}
It will loop at most 1+log_2(a) times. Could be faster if you swap a and b when a > b.
import java.math.BigInteger;
public class MultiplyTest {
public static void main(String[] args) {
BigInteger bigInt1 = new BigInteger("5");
BigInteger bigInt2 = new BigInteger("8");
System.out.println(bigInt1.multiply(bigInt2));
}
}
Shift and add doesn't work (even with sign extension) when the multiplicand is negative. Signed multiplication has to be done using Booth encoding:
Starting from the LSB, a change from 0 to 1 is -1; a change from 1 to 0 is 1, otherwise 0. There is also an implicit extra bit 0 below the LSB.
For example, the number 5 (0101) will be encoded as: (1)(-1)(1)(-1). You can verify this is correct:
5 = 2^3 - 2^2 + 2 -1
This algorithm also works with negative numbers in 2's complement form:
-1 in 4-bit 2's complement is 1111. Using the Booth algorithm: (1)(0)(0)(0)(-1), where there is no space for the leftmost bit 1 so we get: (0)(0)(0)(-1) which is -1.
/* Multiply two signed integers using the Booth algorithm */
int booth(int x, int y)
{
int prev_bit = 0;
int result = 0;
while (x != 0) {
int current_bit = x & 0x1;
if (prev_bit & ~current_bit) {
result += y;
} else if (~prev_bit & current_bit) {
result -= y;
}
prev_bit = current_bit;
x = static_cast<unsigned>(x) >> 1;
y <<= 1;
}
if (prev_bit)
result += y;
return result;
}
The above code does not check for overflow. Below is a slightly modified version that multiplies two 16 bit numbers and returns a 32 bit number so it never overflows:
/* Multiply two 16-bit signed integers using the Booth algorithm */
/* Returns a 32-bit signed integer */
int32_t booth(int16_t x, int16_t y)
{
int16_t prev_bit = 0;
int16_t sign_bit = (x >> 16) & 0x1;
int32_t result = 0;
int32_t y1 = static_cast<int32_t>(y);
while (x != 0) {
int16_t current_bit = x & 0x1;
if (prev_bit & ~current_bit) {
result += y1;
} else if (~prev_bit & current_bit) {
result -= y1;
}
prev_bit = current_bit;
x = static_cast<uint16_t>(x) >> 1;
y1 <<= 1;
}
if (prev_bit & ~sign_bit)
result += y1;
return result;
}
unsigned int Multiply( unsigned int a, unsigned int b )
{
int ret = 0;
// For each bit in b
for (int i=0; i<32; i++) {
// If that bit is not equal to zero
if (( b & (1 << i)) != 0) {
// Add it to our return value
ret += a << i;
}
}
return ret;
}
I avoided the sign bit, because it's kind of not the subject of the post. This is an implementation of what Wayne Conrad said basically. Here is another problem is you want to try more low level math operations. Project Euler is cool!
If you can use the log function:
public static final long multiplyUsingShift(int a, int b) {
int absA = Math.abs(a);
int absB = Math.abs(b);
//Find the 2^b which is larger than "a" which turns out to be the
//ceiling of (Log base 2 of b) == numbers of digits to shift
double logBase2 = Math.log(absB) / Math.log(2);
long bits = (long)Math.ceil(logBase2);
//Get the value of 2^bits
long biggerInteger = (int)Math.pow(2, bits);
//Find the difference of the bigger integer and "b"
long difference = biggerInteger - absB;
//Shift "bits" places to the left
long result = absA<<bits;
//Subtract the "difference" "a" times
int diffLoop = Math.abs(a);
while (diffLoop>0) {
result -= difference;
diffLoop--;
}
return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
If you cannot use the log function:
public static final long multiplyUsingShift(int a, int b) {
int absA = Math.abs(a);
int absB = Math.abs(b);
//Get the number of bits for a 2^(b+1) larger number
int bits = 0;
int bitInteger = absB;
while (bitInteger>0) {
bitInteger /= 2;
bits++;
}
//Get the value of 2^bit
long biggerInteger = (int)Math.pow(2, bits);
//Find the difference of the bigger integer and "b"
long difference = biggerInteger - absB;
//Shift "bits" places to the left
long result = absA<<bits;
//Subtract the "difference" "a" times
int diffLoop = absA;
while (diffLoop>0) {
result -= difference;
diffLoop--;
}
return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
I found this to be more efficient:
public static final long multiplyUsingShift(int a, int b) {
int absA = Math.abs(a);
int absB = Math.abs(b);
long result = 0L;
while (absA>0) {
if ((absA&1)>0) result += absB; //Is odd
absA >>= 1;
absB <<= 1;
}
return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
and yet another way.
public static final long multiplyUsingLogs(int a, int b) {
int absA = Math.abs(a);
int absB = Math.abs(b);
long result = Math.round(Math.pow(10, (Math.log10(absA)+Math.log10(absB))));
return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
In C#:
private static string Multi(int a, int b)
{
if (a == 0 || b == 0)
return "0";
bool isnegative = false;
if (a < 0 || b < 0)
{
isnegative = true;
a = Math.Abs(a);
b = Math.Abs(b);
}
int sum = 0;
if (a > b)
{
for (int i = 1; i <= b; i++)
{
sum += a;
}
}
else
{
for (int i = 1; i <= a; i++)
{
sum += b;
}
}
if (isnegative == true)
return "-" + sum.ToString();
else
return sum.ToString();
}
JAVA:Considering the fact, that every number can be splitted into powers of two:
1 = 2 ^ 0
2 = 2 ^ 1
3 = 2 ^ 1 + 2 ^ 0
...
We want to get x where:
x = n * m
So we can achieve that by doing following steps:
1. while m is greater or equal to 2^pow:
1.1 get the biggest number pow, such as 2^pow is lower or equal to m
1.2 multiply n*2^pow and decrease m to m-2^pow
2. sum the results
Sample implementation using recursion:
long multiply(int n, int m) {
int pow = 0;
while (m >= (1 << ++pow)) ;
pow--;
if (m == 1 << pow) return (n << pow);
return (n << pow) + multiply(n, m - (1 << pow));
}
I got this question in last job interview and this answer was accepted.
EDIT: solution for positive numbers
This is the simplest C99/C11 solution for positive numbers:
unsigned multiply(unsigned x, unsigned y) { return sizeof(char[x][y]); }
Another thinking-outside-the-box answer:
BigDecimal a = new BigDecimal(123);
BigDecimal b = new BigDecimal(2);
BigDecimal result = a.multiply(b);
System.out.println(result.intValue());
public static int multiply(int a, int b)
{
int temp = 0;
if (b == 0) return 0;
for (int ii = 0; ii < abs(b); ++ii) {
temp = temp + a;
}
return b >= 0 ? temp : -temp;
}
public static int abs(int val) {
return val>=0 ? val : -val;
}
public static void main(String[] args) {
System.out.print("Enter value of A -> ");
Scanner s=new Scanner(System.in);
double j=s.nextInt();
System.out.print("Enter value of B -> ");
Scanner p=new Scanner(System.in);
double k=p.nextInt();
double m=(1/k);
double l=(j/m);
System.out.print("Multiplication of A & B=> "+l);
}
package com.amit.string;
// Here I am passing two values, 7 and 3 and method getResult() will
// return 21 without use of any operator except the increment operator, ++.
//
public class MultiplyTwoNumber {
public static void main(String[] args) {
int a = 7;
int b = 3;
System.out.println(new MultiplyTwoNumber().getResult(a, b));
}
public int getResult(int i, int j) {
int result = 0;
// Check for loop logic it is key thing it will go 21 times
for (int k = 0; k < i; k++) {
for (int p = 0; p < j; p++) {
result++;
}
}
return result;
}
}
Loop it. Run a loop seven times and iterate by the number you are multiplying with seven.
Pseudocode:
total = 0
multiply = 34
loop while i < 7
total = total + multiply
endloop
A JavaScript approach for positive numbers
function recursiveMultiply(num1, num2){
const bigger = num1 > num2 ? num1 : num2;
const smaller = num1 <= num2 ? num1 : num2;
const indexIncrement = 1;
const resultIncrement = bigger;
return recursiveMultiplyHelper(bigger, smaller, 0, indexIncrement, resultIncrement)
}
function recursiveMultiplyHelper(num1, num2, index, indexIncrement, resultIncrement){
let result = 0;
if (index === num2){
return result;
}
if ((index+indexIncrement+indexIncrement) >= num2){
indexIncrement = 1;
resultIncrement = num1;
} else{
indexIncrement += indexIncrement;
resultIncrement += resultIncrement;
}
result = recursiveMultiplyHelper(num1, num2, (index+indexIncrement), indexIncrement, resultIncrement);
result += resultIncrement;
console.log(num1, num2, index, result);
return result;
}
Think about the normal multiplication method we use
1101 x =>13
0101 =>5
---------------------
1101
0000
1101
0000
===================
1000001 . => 65
Writing the same above in the code
#include<stdio.h>
int multiply(int a, int b){
int res = 0,count =0;
while(b>0) {
if(b & 0x1)
res = res + (a << count);
b = b>>1;
count++;
}
return res;
}
int main() {
printf("Sum of x+y = %d", multiply(5,10));
return 0;
}
Very simple, pal... Each time when you left shift a number it means you are multiplying the number by 2 which means the answer is (x<<3)-x.
To multiply of two numbers without * operator:
int mul(int a,int b) {
int result = 0;
if(b > 0) {
for(int i=1;i<=b;i++){
result += a;
}
}
return result;
}

Categories

Resources