Skip to content

Commit 9a33517

Browse files
refactor: improve bit manipulation helpers docs and validation
1 parent 19b4ced commit 9a33517

4 files changed

Lines changed: 66 additions & 60 deletions

File tree

bit_manipulation/add_binary.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
11
/**
22
* Adds two binary strings and returns the result as a binary string.
33
*
4-
* @param firstBinaryNo - The first binary string.
5-
* @param secondBinaryNo - The second binary string.
4+
* @param firstBinaryNo - The first binary string (only "0" and "1").
5+
* @param secondBinaryNo - The second binary string (only "0" and "1").
66
* @returns The binary sum of the input strings.
7+
*
8+
* @example
9+
* addBinary('101', '11') === '1000'
710
*/
8-
export function addBinary(
9-
firstBinaryNo: string,
10-
secondBinaryNo: string
11-
): string {
12-
let lengthOfFirstNumber: number = firstBinaryNo.length - 1
13-
let lengthOfSecondNumber: number = secondBinaryNo.length - 1
14-
const solution: string[] = []
15-
let carry: number = 0
11+
export function addBinary(firstBinaryNo: string, secondBinaryNo: string): string {
12+
if (!/^[01]+$/.test(firstBinaryNo) || !/^[01]+$/.test(secondBinaryNo)) {
13+
throw new TypeError('Inputs must be non-empty binary strings containing only "0" or "1".')
14+
}
15+
16+
let i = firstBinaryNo.length - 1
17+
let j = secondBinaryNo.length - 1
18+
const result: string[] = []
19+
let carry = 0
20+
21+
while (i >= 0 || j >= 0) {
22+
let sum = carry
23+
if (i >= 0) sum += parseInt(firstBinaryNo.charAt(i), 10)
24+
if (j >= 0) sum += parseInt(secondBinaryNo.charAt(j), 10)
1625

17-
while (lengthOfFirstNumber >= 0 || lengthOfSecondNumber >= 0) {
18-
let sum: number = carry
19-
if (lengthOfFirstNumber >= 0)
20-
sum += parseInt(firstBinaryNo.charAt(lengthOfFirstNumber))
21-
if (lengthOfSecondNumber >= 0)
22-
sum += parseInt(secondBinaryNo.charAt(lengthOfSecondNumber))
23-
solution.push((sum % 2).toString())
26+
result.push((sum % 2).toString())
2427
carry = Math.floor(sum / 2)
25-
lengthOfFirstNumber--
26-
lengthOfSecondNumber--
28+
i--
29+
j--
2730
}
2831

29-
if (carry !== 0) solution.push(carry.toString())
32+
if (carry !== 0) result.push(carry.toString())
3033

31-
return solution.reverse().join('')
32-
}
34+
return result.reverse().join('')
35+
}

bit_manipulation/is_power_of_2.ts

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
/**
2-
* This code will check whether the given number is a power of two or not.
3-
* @author dev-madhurendra<https://github.com/dev-madhurendra>
4-
* @explanation
5-
6-
A number will be a power of two if only one bit is set and rest are unset.
7-
This is true for all the cases except 01 because (2^0 = 1) which is not a power of 2.
8-
For eg: 10 (2^1 = 2), 100 (2^2 = 4), 10000 (2^4 = 16)
9-
10-
@see: https://www.hackerearth.com/practice/notes/round-a-number-to-the-next-power-of-2/
11-
12-
If we will subtract 1 from a number that is a power of 2 we will get it's
13-
1's complement.And we know that 1's complement is just opp. of that number.
14-
So, (n & (n-1)) will be 0.
15-
16-
For eg: (1000 & (1000-1))
17-
1 0 0 0 // Original Number (8)
18-
0 1 1 1 // After Subtracting 1 (8-1 = 7)
19-
_______
20-
0 0 0 0 // will become 0
21-
* @param {number}
22-
* @returns {boolean}
2+
* Checks whether the given number is a power of two.
3+
*
4+
* A positive integer is a power of two if and only if it has exactly one bit set in its
5+
* binary representation. Examples: 1 (2^0), 2 (2^1), 4 (2^2), 16 (2^4).
6+
*
7+
* The expression (n & (n - 1)) clears the lowest set bit of n. For powers of two
8+
* this becomes zero, so n & (n - 1) === 0.
9+
*
10+
* @author dev-madhurendra <https://github.com/dev-madhurendra>
11+
* @param n - The number to test.
12+
* @returns true if n is a power of two; otherwise false. Returns false for n <= 0.
2313
*/
24-
25-
export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0
14+
export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0

bit_manipulation/is_power_of_4.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
/**
2-
* @author : dev-madhurendra<https://github.com/dev-madhurendra>
3-
* Checks whether the given number is a power of four or not.
2+
* Checks whether the given number is a power of four.
43
*
5-
* A number is considered a power of four if and only if there is a single '1' bit in its binary representation,
6-
* and that '1' bit is at the first position, followed by an even number of '0' bits.
4+
* A positive integer is a power of four if:
5+
* - it is a power of two (exactly one bit set), and
6+
* - that bit is in an even position (0-based), e.g. 1 (2^0), 4 (2^2), 16 (2^4), ...
77
*
8-
* @param {number} n - The input number to check.
9-
* @returns {boolean} True if the number is a power of four, false otherwise.
8+
* This implementation uses the property that for powers of four: n % 3 === 1.
9+
*
10+
* @author dev-madhurendra <https://github.com/dev-madhurendra>
11+
* @param n - The number to check.
12+
* @returns true if n is a power of four; otherwise false.
1013
*
1114
* @example
12-
* const result = isPowerOfFour(16); // Returns true (16 is 4^2)
13-
* const result2 = isPowerOfFour(5); // Returns false (5 is not a power of four)
15+
* isPowerOfFour(16) // true (16 = 4^2)
16+
* isPowerOfFour(5) // false
1417
*/
1518
export const isPowerOfFour = (n: number): boolean =>
16-
n > 0 && (n & (n - 1)) === 0 && n % 3 === 1
19+
n > 0 && (n & (n - 1)) === 0 && n % 3 === 1

bit_manipulation/log_two.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
/**
2+
* Approximate base-2 logarithm using bitwise operators.
3+
*
4+
* Returns floor(log2(n)) for positive integers n. Throws a RangeError for n <= 0.
5+
*
26
* @author dev-madhurendra <https://github.com/dev-madhurendra>
37
* @see https://handwiki.org/wiki/Binary_logarithm
4-
* Approximate log2 using bitwise operators
5-
* @param {number} n
6-
* @returns {number} Log2 approximation equal to floor(log2(n))
8+
* @param n - Positive integer input.
9+
* @returns floor(log2(n)).
10+
* @throws RangeError if n <= 0.
711
*/
812
export const logTwo = (n: number): number => {
13+
if (n <= 0) {
14+
throw new RangeError('logTwo is only defined for positive integers.')
15+
}
16+
17+
let x = n
918
let result = 0
10-
while (n >> 1) {
11-
n >>= 1
19+
20+
while (x >> 1) {
21+
x >>= 1
1222
result++
1323
}
24+
1425
return result
15-
}
26+
}

0 commit comments

Comments
 (0)