Minor code style fixes for bitwise multiplication.

This commit is contained in:
Oleksii Trekhleb 2018-09-08 23:09:04 +03:00
parent bc8943dee2
commit de6a24e0d1
5 changed files with 41 additions and 17 deletions

View File

@ -38,12 +38,14 @@ This method is a combination of "Clear Bit" and "Set Bit" methods.
#### isEven #### isEven
This method determines if the number provided is even. This method determines if the number provided is even.
It is based on the fact that odd numbers have their last
right bit to be set to 1.
``` ```text
Number: 5 Number: 5 = 0b0101
isEven: false isEven: false
Number: 4 Number: 4 = 0b0100
isEven: true isEven: true
``` ```
@ -108,18 +110,19 @@ inverting all of the bits of the number and adding 1 to it.
#### Multiply Two Signed Numbers #### Multiply Two Signed Numbers
This method multiplies two signed integer numbers using bitwise operators. This method multiplies two signed integer numbers using bitwise operators.
This method is based on the following : This method is based on the following facts:
```text ```text
a * b can be written in the below formats 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 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/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 positive
2a * (b + 1)/2 - a if b is odd and negative 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. The advantage of this approach is that in each recursive step one of the operands
Hence, the run time complexity is O(log b) where b is the operand that reduces to half on each recursive step. 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. > See [multiply.js](multiply.js) for further details.

View File

@ -7,5 +7,13 @@ describe('isEven', () => {
expect(isEven(-2)).toBe(true); expect(isEven(-2)).toBe(true);
expect(isEven(1)).toBe(false); expect(isEven(1)).toBe(false);
expect(isEven(-1)).toBe(false); expect(isEven(-1)).toBe(false);
expect(isEven(-3)).toBe(false);
expect(isEven(3)).toBe(false);
expect(isEven(8)).toBe(true);
expect(isEven(9)).toBe(false);
expect(isEven(121)).toBe(false);
expect(isEven(122)).toBe(true);
expect(isEven(1201)).toBe(false);
expect(isEven(1202)).toBe(true);
}); });
}); });

View File

@ -12,5 +12,7 @@ describe('multiply', () => {
expect(multiply(4, -2)).toBe(-8); expect(multiply(4, -2)).toBe(-8);
expect(multiply(-4, -4)).toBe(16); expect(multiply(-4, -4)).toBe(16);
expect(multiply(4, -5)).toBe(-20); expect(multiply(4, -5)).toBe(-20);
expect(multiply(2, 121)).toBe(242);
expect(multiply(121, 2)).toBe(242);
}); });
}); });

View File

@ -1,6 +1,6 @@
/** /**
* @param {number} number * @param {number} number
* @return bool * @return {boolean}
*/ */
export default function isEven(number) { export default function isEven(number) {
return (number & 1) === 0; return (number & 1) === 0;

View File

@ -1,27 +1,38 @@
import multiplyByTwo from './multiplyByTwo';
import divideByTwo from './divideByTwo'; import divideByTwo from './divideByTwo';
import isEven from './isEven'; import isEven from './isEven';
import multiplyByTwo from './multiplyByTwo';
/** /**
* FUNCTION DEFINITION * Multiply two signed numbers using bitwise operations.
* 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 * If a is zero or b is zero or if both a and b are zeros:
* multiply(a, b) = multiply(2a, (b-1)/2) + a if b is odd and b is positive * multiply(a, b) = 0
* multiply(a, b) = multiply(2a, (b+1)/2) - a if b is odd and b is negative *
* If b is even:
* multiply(a, b) = multiply(2a, b/2)
*
* 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:
* multiply(a, b) = multiply(2a, (b+1)/2) - a
*
* Time complexity: O(log b)
* *
* COMPLEXITY
* O(log b)
* @param {number} a * @param {number} a
* @param {number} b * @param {number} b
* @return {number} a * b * @return {number}
*/ */
export default function multiply(a, b) { export default function multiply(a, b) {
// If a is zero or b is zero or if both a and b are zeros then the production is also zero.
if (b === 0 || a === 0) { if (b === 0 || a === 0) {
return 0; return 0;
} }
// Otherwise we will have four different cases that are described above.
const multiplyByOddPositive = () => multiply(multiplyByTwo(a), divideByTwo(b - 1)) + a; const multiplyByOddPositive = () => multiply(multiplyByTwo(a), divideByTwo(b - 1)) + a;
const multiplyByOddNegative = () => multiply(multiplyByTwo(a), divideByTwo(b + 1)) - a; const multiplyByOddNegative = () => multiply(multiplyByTwo(a), divideByTwo(b + 1)) - a;
const multiplyByEven = () => multiply(multiplyByTwo(a), divideByTwo(b)); const multiplyByEven = () => multiply(multiplyByTwo(a), divideByTwo(b));
const multiplyByOdd = () => (b > 0 ? multiplyByOddPositive() : multiplyByOddNegative()); const multiplyByOdd = () => (b > 0 ? multiplyByOddPositive() : multiplyByOddNegative());