mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 23:21:18 +08:00
Perform multiplication of any two integers positive or negative through bit manipulations (#201)
This commit is contained in:
parent
1a62078f26
commit
bc8943dee2
@ -35,6 +35,20 @@ This method is a combination of "Clear Bit" and "Set Bit" methods.
|
|||||||
|
|
||||||
> See [updateBit.js](updateBit.js) for further details.
|
> See [updateBit.js](updateBit.js) for further details.
|
||||||
|
|
||||||
|
#### isEven
|
||||||
|
|
||||||
|
This method determines if the number provided is even.
|
||||||
|
|
||||||
|
```
|
||||||
|
Number: 5
|
||||||
|
isEven: false
|
||||||
|
|
||||||
|
Number: 4
|
||||||
|
isEven: true
|
||||||
|
```
|
||||||
|
|
||||||
|
> See [isEven.js](isEven.js) for further details.
|
||||||
|
|
||||||
#### Multiply By Two
|
#### Multiply By Two
|
||||||
|
|
||||||
This method shifts original number by one bit to the left.
|
This method shifts original number by one bit to the left.
|
||||||
@ -91,7 +105,25 @@ inverting all of the bits of the number and adding 1 to it.
|
|||||||
|
|
||||||
> See [switchSign.js](switchSign.js) for further details.
|
> See [switchSign.js](switchSign.js) for further details.
|
||||||
|
|
||||||
#### Multiply Two Numbers
|
#### Multiply Two Signed Numbers
|
||||||
|
|
||||||
|
This method multiplies two signed integer numbers using bitwise operators.
|
||||||
|
This method is based on the following :
|
||||||
|
|
||||||
|
```text
|
||||||
|
a * b can be written in the below formats
|
||||||
|
0 if a is zero or b is zero or both a and b are zeroes
|
||||||
|
2a * (b/2) if b is even
|
||||||
|
2a * (b - 1)/2 + a if b is odd and positive
|
||||||
|
2a * (b + 1)/2 - a if b is odd and negative
|
||||||
|
```
|
||||||
|
|
||||||
|
The advantage of this approach is that in each recursive step one of the operands reduces to half its original value.
|
||||||
|
Hence, the run time complexity is O(log b) where b is the operand that reduces to half on each recursive step.
|
||||||
|
|
||||||
|
> See [multiply.js](multiply.js) for further details.
|
||||||
|
|
||||||
|
#### Multiply Two Unsigned Numbers
|
||||||
|
|
||||||
This method multiplies two integer numbers using bitwise operators.
|
This method multiplies two integer numbers using bitwise operators.
|
||||||
This method is based on that "Every number can be denoted as the sum of powers of 2".
|
This method is based on that "Every number can be denoted as the sum of powers of 2".
|
||||||
|
11
src/algorithms/math/bits/__test__/isEven.test.js
Normal file
11
src/algorithms/math/bits/__test__/isEven.test.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import isEven from '../isEven';
|
||||||
|
|
||||||
|
describe('isEven', () => {
|
||||||
|
it('should detect if a number is even', () => {
|
||||||
|
expect(isEven(0)).toBe(true);
|
||||||
|
expect(isEven(2)).toBe(true);
|
||||||
|
expect(isEven(-2)).toBe(true);
|
||||||
|
expect(isEven(1)).toBe(false);
|
||||||
|
expect(isEven(-1)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
16
src/algorithms/math/bits/__test__/multiply.test.js
Normal file
16
src/algorithms/math/bits/__test__/multiply.test.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import multiply from '../multiply';
|
||||||
|
|
||||||
|
describe('multiply', () => {
|
||||||
|
it('should multiply two numbers', () => {
|
||||||
|
expect(multiply(0, 0)).toBe(0);
|
||||||
|
expect(multiply(2, 0)).toBe(0);
|
||||||
|
expect(multiply(0, 2)).toBe(0);
|
||||||
|
expect(multiply(1, 2)).toBe(2);
|
||||||
|
expect(multiply(2, 1)).toBe(2);
|
||||||
|
expect(multiply(6, 6)).toBe(36);
|
||||||
|
expect(multiply(-2, 4)).toBe(-8);
|
||||||
|
expect(multiply(4, -2)).toBe(-8);
|
||||||
|
expect(multiply(-4, -4)).toBe(16);
|
||||||
|
expect(multiply(4, -5)).toBe(-20);
|
||||||
|
});
|
||||||
|
});
|
7
src/algorithms/math/bits/isEven.js
Normal file
7
src/algorithms/math/bits/isEven.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @param {number} number
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
export default function isEven(number) {
|
||||||
|
return (number & 1) === 0;
|
||||||
|
}
|
29
src/algorithms/math/bits/multiply.js
Normal file
29
src/algorithms/math/bits/multiply.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import divideByTwo from './divideByTwo';
|
||||||
|
import isEven from './isEven';
|
||||||
|
import multiplyByTwo from './multiplyByTwo';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DEFINITION
|
||||||
|
* multiply(a, b) = 0 if a is zero or b is zero or if both a and b are zeros
|
||||||
|
* multiply(a, b) = multiply(2a, b/2) if b is even
|
||||||
|
* multiply(a, b) = multiply(2a, (b-1)/2) + a if b is odd and b is positive
|
||||||
|
* multiply(a, b) = multiply(2a, (b+1)/2) - a if b is odd and b is negative
|
||||||
|
*
|
||||||
|
* COMPLEXITY
|
||||||
|
* O(log b)
|
||||||
|
* @param {number} a
|
||||||
|
* @param {number} b
|
||||||
|
* @return {number} a * b
|
||||||
|
*/
|
||||||
|
export default function multiply(a, b) {
|
||||||
|
if (b === 0 || a === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const multiplyByOddPositive = () => multiply(multiplyByTwo(a), divideByTwo(b - 1)) + a;
|
||||||
|
const multiplyByOddNegative = () => multiply(multiplyByTwo(a), divideByTwo(b + 1)) - a;
|
||||||
|
const multiplyByEven = () => multiply(multiplyByTwo(a), divideByTwo(b));
|
||||||
|
const multiplyByOdd = () => (b > 0 ? multiplyByOddPositive() : multiplyByOddNegative());
|
||||||
|
|
||||||
|
return isEven(b) ? multiplyByEven() : multiplyByOdd();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user