Consider a hexadecimal integer value such as n = 0x12345, how to get 0x1235 as result by doing remove(n, 3) (big endian)?
For the inputs above I think this can be achieved by performing some bitwising steps:
partA = extract the part from index 0 to targetIndex - 1 (should return 0x123);
partB = extract the part from targetIndex + 1 to length(value) - 1 (0x5);
result, then, can be expressed by ((partA << length(partB) | partB), giving the 0x1235 result.
However I'm still confused in how to implement it, once each hex digit occupies 4 spaces. Also, I don't know a good way to retrieve the length of the numbers.
This can be easily done with strings however I need to use this in a context of thousands of iterations and don't think Strings is a good idea to choose.
So, what is a good way to this removing without Strings?
Similar to the idea you describe, this can be done by creating a mask for both the upper and the lower part, shifting the upper part, and then reassembling.
int remove(int x, int i) {
// create a mask covering the highest 1-bit and all lower bits
int m = x;
m |= (m >>> 1);
m |= (m >>> 2);
m |= (m >>> 4);
m |= (m >>> 8);
m |= (m >>> 16);
// clamp to 4-bit boundary
int l = m & 0x11111110;
m = l - (l >>> 4);
// shift to select relevant position
m >>>= 4 * i;
// assemble result
return ((x & ~(m << 4)) >>> 4) | (x & m);
}
where ">>>" is an unsigned shift.
As a note, if 0 indicates the highest hex digit in a 32-bit word independent of the input, this is much simpler:
int remove(int x, int i) {
int m = 0xffffffff >>> (4*i);
return ((x & ~m) >>> 4) | (x & (m >>> 4));
}
Solution:
Replace operations using 10 with operations using 16.
Demo
Using Bitwise Operator:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
Using Math::pow:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= ((int) (Math.pow(16, length - index - 1)));
m += n % ((int) (Math.pow(16, length - index - 1)));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
JavaScript version:
n = parseInt(12345, 16);
temp = n;
length = 0;
// Find length
while (temp != 0) {
length++;
temp = Math.floor(temp / 16);
}
console.log("Length of the number: " + length);
// Remove digit at index 3
m = n;
index = 3;
for (i = index + 1; i <= length; i++) {
m = Math.floor(m / 16);
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
console.log("The number after removing digit at index " + index + ": 0x" + m.toString(16));
This works by writing a method to remove from the right but adjusting the parameter to remove from the left. The bonus is that a remove from the right is also available for use. This method uses longs to maximize the length of the hex value.
long n = 0x12DFABCA12L;
int r = 3;
System.out.println("Supplied value: " + Long.toHexString(n).toUpperCase());
n = removeNthFromTheRight(n, r);
System.out.printf("Counting %d from the right: %X%n", r, n);
n = 0x12DFABCA12L;
n = removeNthFromTheLeft(n, r);
System.out.printf("Counting %d from the left: %X%n", r, n);
Prints
Supplied value: 12DFABCA12
Counting 3 from the right: 12DFABA12
Counting 3 from the left: 12DABCA12
This works by recursively removing a digit from the end until just before the one you want to remove. Then remove that and return thru the call stack, rebuilding the number with the original values.
This method counts from the right.
public static long removeNthFromTheRight(long v, int n) {
if (v <= 0) {
throw new IllegalArgumentException("Not enough digits");
}
// save hex digit
long k = v % 16;
while (n > 0) {
// continue removing digit until one
// before the one you want to remove
return removeNthFromTheRight(v / 16, n - 1) * 16 + k;
}
if (n == 0) {
// and ignore that digit.
v /= 16;
}
return v;
}
This method counts from the left. It simply adjusts the value of n and then calls removeFromTheRight.
public static long removeNthFromTheLeft(long v, int n) {
ndigits = (67-Long.numberOfLeadingZeros(v))>>2;
// Now just call removeNthFromTheRight with modified paramaters.
return removeNthFromTheRight(v, ndigits - n - 1);
}
Here is my version using bit manipulation with explanation.
the highest set bit helps find the offset for the mask. For a long that bit is 64-the number of leading zeroes. To get the number of hex digits, one must divide by 4. To account for numbers evenly divisible by 4, it is necessary to add 3 before dividing. So that makes the number of digits:
digits = (67-Long.numberOfLeadingZeros(i))>>2;
which then requires it to be adjusted to mask the appropriate parts of the number.
offset = digits-i - 1
m is the mask to mask off the digit to be removed. So start with a -1L (all hex 'F') and right shift 4*(16-offset) bits. This will result in a mask that masks everything to the right of the digit to be removed.
Note: If offset is 0 the shift operator will be 64 and no bits will be shifted. To accommodate this, the shift operation is broken up into two operations.
Now simply mask off the low order bits
v & m
And the high order bits right shifted 4 bits to eliminate the desired digit.
(v>>>4)^ ~m
and then the two parts are simply OR'd together.
static long remove(long v, int i) {
int offset = ((67 - Long.numberOfLeadingZeros(v))>>2) - i - 1;
long m = (-1L >>> (4*(16 - offset) - 1)) >> 1;
return ((v >>> 4) & ~m) | (v & m);
}
I tested the below code with all ASCII values from 64 - 90 inclusive (All uppercase letters) and adjusted accordingly so instead of:
for(int i = 0 ; i < c.length(); i++){
info[i] = ((int)c.charAt(i) - 32);
}
I would replace the 32 with 64 (so the ASCII value of A would save in the array as 0). Furthermore, in my encryption and decryption functions I would replace 95 with 26 (26 letters).
However, if I apply this to all values between 32-126 inclusive (95 characters) and adjust the values accordingly, the values become incorrect and I don't know why. Here is my whole main function below (note that the formula used in encryption and decryption is just an example one I used and I plan on changing the values later on):
public static void main(String[] args) {
String c = "sd344rf"; // could be any set of characters within the range
int[] e = new int[c.length()]; // encrypted set
int[] d = new int[c.length()]; // decrypted set
int[] info = new int[c.length()];
for(int i = 0 ; i < c.length(); i++){
info[i] = ((int)c.charAt(i) - 32);
}
for(int i = 0; i < c.length(); i++){
e[i] = encryption(info[i]);
}
for(int i = 0; i < c.length(); i++){
d[i] = decryption(e[i]);
}
display(info);
System.out.println();
display(e);
System.out.println();
display(d);
}
public static int encryption(int x){
return mod(3*x + 9,95);
}
public static int decryption(int x){
return mod(9*x - 3,95);
}
public static void display(int[] arr){
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
Obviously you are trying to implement an affine cipher. For an affine cipher the encryption is
y = mod(n * x + s, m)
and the decryption
x = mod(ni * (y - s), m)
with
x: Value of the character to encrypt
y: Value of the encrypted character
m: Number of characters in the underlying alphabet
n, s: Key of the encryption
n and s must be chosen so that they are between 0 and m - 1, inclusive. In addition, n has to be chosen so that n and m are coprime. ni is the modular multiplicative inverse of n modulo m and is determined by n*ni mod m = 1.
This is in more detail explained at https://en.wikipedia.org/wiki/Affine_cipher.
If the values u, v associated with the characters don't start at 0 the values have to be shifted by an offset equal to the value of the first character (provided that there are no gaps) and the formulas become
x = u - offset
y = v - offset
v = mod(n * (u - offset) + s, m) + offset
u = mod(ni * ((v - offset) - s), m) + offset
Thus, you've to replace in the main-method
info[i] = ((int)c.charAt(i) - 32);
with
info[i] = (int)c.charAt(i);
The encryption-method becomes:
public static int encryption(int u) {
return mod(n * (u - offset) + s, m) + offset;
}
and the decryption-method
public static int decryption(int v) {
return mod(ni * ((v - offset) - s), m) + offset;
}
with the fields
private static int m = <Number of the characters in the alphabet>;
private static int n = <Key (factor)>; // n between 0 and m-1 and moreover, n and m have te be coprime
private static int s = <Key (summand)>; // s between 0 and m-1
private static int offset = <Value of the first character of the alphabet>;
private static int ni = <Modular multiplicative inverse of n modulo m>;
Moreover, for the mod-operation the following method is used (see Encryption/decryption program not working properly):
private static int mod(int a, int b) {
return ((a % b) + b) % b;
}
Example 1: Uppercase letters A - Z:
private static int m = 'Z' - 'A' + 1; // 26
private static int n = 3; // Choose e.g. n = 3: n = 3 < 26 - 1 = 25 and moreover, 3 and 26 are coprime
private static int s = 9; // Choose e.g. s = 9: s = 9 < 26 - 1 = 25
private static int offset = 'A'; // 65
private static int ni = 9; // 3*9 mod 26 = 1
Test:
String c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Output (with characters instead of their values):
Plain text: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Encrypted text: JMPSVYBEHKNQTWZCFILORUXADG
Decrypted text: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Example 2: All characters between 32 (Space) and 126 (~), inclusive:
private static int m = '~' - ' ' + 1; // 95
private static int n = 3; // Choose e.g. n = 3: n = 3 < 95 - 1 = 94 and moreover, 3 and 95 are coprime
private static int s = 9; // Choose e.g. s = 9: s = 9 < 95 - 1 = 94
private static int offset = ' '; // 32
private static int ni = 32; // 3*32 mod 95 = 1
Test:
String c = " !\"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
Output (with characters instead of their values):
Plain text: !"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Encrypted text: ),/258;>ADGJMPSVY\_behknqtwz}!$'*-0369<?BEHKNQTWZ]`cfilorux{~"%(+.147:=#CFILORUX[^adgjmpsvy| #&
Decrypted text: !"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
I have a homework assignment where I have to covert any base to base 10. I have some given numbers, which are the "basen". I have to convert those bases to base 10. The only part that I am stuck in is this part of the code:
answer = ; // Not sure what I have to put in here
I have seen some other posts about converting to base ten, but I am just not sure how to how to incorporate them into my code.
public class BaseN {
public static final int BASEN_ERRNO = -1;
public static int digit = 0;
public static void main(String[] argv) {
basen(512, 6);
basen(314, 8);
basen(49, 5);
basen(10101, 2);
}
public static void basen(int n, int b) {
int ans = basen(n, b, 1, 0);
if (ans == BASEN_ERRNO)
System.out.println(n + " is not a valid base-" + b + " number");
else
System.out.println(n + " base-" + b + " = " + ans + " base-10");
}
public static int basen(int number, int base, int placevalue, int answer) {
if (number == 0) return answer;
digit = number % 10;
if (digit >= base) return BASEN_ERRNO;
answer = 1;// not sure what to put here
number = 0;
placevalue = 0;
return basen(number, base, placevalue, answer);
}
}
You could look at a k length number of base n like this:
x(0)*n^(k-1) + x(1)*n^(k-2) + ... + x(k-1)*n^1 + x(k)*n^0
Where x(0), x(1), ..., x(k) is the digit at position k from the left.
So, if you are trying to convert, say, 101 base 2 to base 10 you would do the following :
1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 4 + 0 + 1 = 5 base 10
say you want to convert the number 352 from base 6:
3 * 6^2 + 5 * 6^1 + 2 * 6^0 = 108 + 30 + 2 = 145 base 10
What you're looking for code wise is something like this :
int[] digits = {3, 5, 2};
int base = 6;
int answer = 0;
for(int i = digits.length - 1; i >= 0; i--)
{
answer += digits[i] * Math.pow(base,digits.length-i-1);
}
return answer;
which will return 145.
Hopefully even though my implementation is iterative you should be able to apply it to your recursive implementation as well.
You can implement the following algorithm. Lets say you are given String number which represents the number you want to convert to decimal form and int base which represents the base of given number. You can implement function int convertToNumber(char c); which accepts one character representing one digit from your number and will map characters to numbers like this:
0 -> 0,
1 -> 1,
... ,
A-> 10,
B -> 11,
... ,
F -> 15,
...
Then you just iterate through your given string and multiply this functions output with base to the power of iteration. For example, convert number A32(hexadecimal):
A32 = convertToNumber(A) * b ^ 2 + convertToNumber(3) * b ^ 1 + convertToNumber(2) * b ^ 0 = 10 * 16 ^ 2 + 3 * 16 ^ 1 + 2 * 16 ^ 0 = 10 * 16 * 16 + 3 * 16 + 2 = 2610 (decimal).
public class BaseConvert {
public static int convertDigitToNumber(char c) throws Exception {
if(c >= '0' && c <= '9') return c - '0';
if(c >= 'A' && c <= 'Z') return c - 55;
if(c >= 'a' && c <= 'z') return c - 97;
throw new Exception("Invalid digit!");
}
public static int convertToBase(String number, int base) throws Exception {
int result = 0;
for(int i = 0; i < number.length(); i++){
result += convertDigitToNumber(number.charAt(i)) * (int)Math.pow(base, number.length() - i - 1);
}
return result;
}
public static void main(String[] args) {
try{
System.out.println(convertToBase("732", 8));
System.out.println(convertToBase("A32", 16));
System.out.println(convertToBase("1010", 2));
}catch (Exception e) {
System.out.print(e);
}
}
}
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;
}