Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/algorithms/math/bits/__test__/multiplyUnsigned.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import multiplyUnsigned from '../multiplyUnsigned';

describe('multiplyUnsigned', () => {
it.each([
[0, 0x80000000, 0],
[1, 0x80000000, 0x80000000],
[1, 0xffffffff, 0xffffffff],
[2, 0xffffffff, 8589934590],
[0xffffffff, 2, 8589934590],
[65535, 65535, 4294836225],
])('should multiply %i by %i without signed overflow', (a, b, product) => {
expect(multiplyUnsigned(a, b)).toBe(product);
});

it('should multiply two unsigned numbers', () => {
expect(multiplyUnsigned(0, 2)).toBe(0);
expect(multiplyUnsigned(2, 0)).toBe(0);
Expand Down
19 changes: 9 additions & 10 deletions src/algorithms/math/bits/multiplyUnsigned.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Multiply to unsigned numbers using bitwise operator.
* Multiply two unsigned 32-bit integers using bitwise operations.
*
* The main idea of bitwise multiplication is that every number may be split
* to the sum of powers of two:
Expand All @@ -10,7 +10,8 @@
*
* x * 19 = x * 2^4 + x * 2^1 + x * 2^0
*
* Now we need to remember that (x * 2^4) is equivalent of shifting x left by 4 bits (x << 4).
* Doubling x advances to the next power of two. Use numeric addition for this
* step because JavaScript's left shift truncates the result to a signed 32-bit integer.
*
* @param {number} number1
* @param {number} number2
Expand All @@ -22,21 +23,19 @@ export default function multiplyUnsigned(number1, number2) {
// Let's treat number2 as a multiplier for the number1.
let multiplier = number2;

// Multiplier current bit index.
let bitIndex = 0;
// Value of number1 multiplied by the current power of two.
let multiplicand = number1;

// Go through all bits of number2.
while (multiplier !== 0) {
// Check if current multiplier bit is set.
if (multiplier & 1) {
// In case if multiplier's bit at position bitIndex is set
// it would mean that we need to multiply number1 by the power
// of bit with index bitIndex and then add it to the result.
result += (number1 << bitIndex);
result += multiplicand;
}

bitIndex += 1;
multiplier >>= 1;
multiplicand += multiplicand;
// Zero-fill the high bit so unsigned values eventually reach zero.
multiplier >>>= 1;
}

return result;
Expand Down