From 9a33517e637fe3ac63fb0bd7feb2991a9affcebf Mon Sep 17 00:00:00 2001 From: Ashish agarwal Date: Sun, 28 Jun 2026 22:34:50 +0530 Subject: [PATCH] refactor: improve bit manipulation helpers docs and validation --- bit_manipulation/add_binary.ts | 47 ++++++++++++++++--------------- bit_manipulation/is_power_of_2.ts | 35 ++++++++--------------- bit_manipulation/is_power_of_4.ts | 21 ++++++++------ bit_manipulation/log_two.ts | 23 +++++++++++---- 4 files changed, 66 insertions(+), 60 deletions(-) diff --git a/bit_manipulation/add_binary.ts b/bit_manipulation/add_binary.ts index 7e6ecd03..8914e172 100644 --- a/bit_manipulation/add_binary.ts +++ b/bit_manipulation/add_binary.ts @@ -1,32 +1,35 @@ /** * Adds two binary strings and returns the result as a binary string. * - * @param firstBinaryNo - The first binary string. - * @param secondBinaryNo - The second binary string. + * @param firstBinaryNo - The first binary string (only "0" and "1"). + * @param secondBinaryNo - The second binary string (only "0" and "1"). * @returns The binary sum of the input strings. + * + * @example + * addBinary('101', '11') === '1000' */ -export function addBinary( - firstBinaryNo: string, - secondBinaryNo: string -): string { - let lengthOfFirstNumber: number = firstBinaryNo.length - 1 - let lengthOfSecondNumber: number = secondBinaryNo.length - 1 - const solution: string[] = [] - let carry: number = 0 +export function addBinary(firstBinaryNo: string, secondBinaryNo: string): string { + if (!/^[01]+$/.test(firstBinaryNo) || !/^[01]+$/.test(secondBinaryNo)) { + throw new TypeError('Inputs must be non-empty binary strings containing only "0" or "1".') + } + + let i = firstBinaryNo.length - 1 + let j = secondBinaryNo.length - 1 + const result: string[] = [] + let carry = 0 + + while (i >= 0 || j >= 0) { + let sum = carry + if (i >= 0) sum += parseInt(firstBinaryNo.charAt(i), 10) + if (j >= 0) sum += parseInt(secondBinaryNo.charAt(j), 10) - while (lengthOfFirstNumber >= 0 || lengthOfSecondNumber >= 0) { - let sum: number = carry - if (lengthOfFirstNumber >= 0) - sum += parseInt(firstBinaryNo.charAt(lengthOfFirstNumber)) - if (lengthOfSecondNumber >= 0) - sum += parseInt(secondBinaryNo.charAt(lengthOfSecondNumber)) - solution.push((sum % 2).toString()) + result.push((sum % 2).toString()) carry = Math.floor(sum / 2) - lengthOfFirstNumber-- - lengthOfSecondNumber-- + i-- + j-- } - if (carry !== 0) solution.push(carry.toString()) + if (carry !== 0) result.push(carry.toString()) - return solution.reverse().join('') -} + return result.reverse().join('') +} \ No newline at end of file diff --git a/bit_manipulation/is_power_of_2.ts b/bit_manipulation/is_power_of_2.ts index 2edcea31..c4f7ad6d 100644 --- a/bit_manipulation/is_power_of_2.ts +++ b/bit_manipulation/is_power_of_2.ts @@ -1,25 +1,14 @@ /** - * This code will check whether the given number is a power of two or not. - * @author dev-madhurendra - * @explanation - - A number will be a power of two if only one bit is set and rest are unset. - This is true for all the cases except 01 because (2^0 = 1) which is not a power of 2. - For eg: 10 (2^1 = 2), 100 (2^2 = 4), 10000 (2^4 = 16) - - @see: https://www.hackerearth.com/practice/notes/round-a-number-to-the-next-power-of-2/ - - If we will subtract 1 from a number that is a power of 2 we will get it's - 1's complement.And we know that 1's complement is just opp. of that number. - So, (n & (n-1)) will be 0. - - For eg: (1000 & (1000-1)) - 1 0 0 0 // Original Number (8) - 0 1 1 1 // After Subtracting 1 (8-1 = 7) - _______ - 0 0 0 0 // will become 0 - * @param {number} - * @returns {boolean} + * Checks whether the given number is a power of two. + * + * A positive integer is a power of two if and only if it has exactly one bit set in its + * binary representation. Examples: 1 (2^0), 2 (2^1), 4 (2^2), 16 (2^4). + * + * The expression (n & (n - 1)) clears the lowest set bit of n. For powers of two + * this becomes zero, so n & (n - 1) === 0. + * + * @author dev-madhurendra + * @param n - The number to test. + * @returns true if n is a power of two; otherwise false. Returns false for n <= 0. */ - -export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0 +export const isPowerOfTwo = (n: number): boolean => n > 0 && (n & (n - 1)) === 0 \ No newline at end of file diff --git a/bit_manipulation/is_power_of_4.ts b/bit_manipulation/is_power_of_4.ts index 1e5e2d5a..1cb36fbe 100644 --- a/bit_manipulation/is_power_of_4.ts +++ b/bit_manipulation/is_power_of_4.ts @@ -1,16 +1,19 @@ /** - * @author : dev-madhurendra - * Checks whether the given number is a power of four or not. + * Checks whether the given number is a power of four. * - * A number is considered a power of four if and only if there is a single '1' bit in its binary representation, - * and that '1' bit is at the first position, followed by an even number of '0' bits. + * A positive integer is a power of four if: + * - it is a power of two (exactly one bit set), and + * - that bit is in an even position (0-based), e.g. 1 (2^0), 4 (2^2), 16 (2^4), ... * - * @param {number} n - The input number to check. - * @returns {boolean} True if the number is a power of four, false otherwise. + * This implementation uses the property that for powers of four: n % 3 === 1. + * + * @author dev-madhurendra + * @param n - The number to check. + * @returns true if n is a power of four; otherwise false. * * @example - * const result = isPowerOfFour(16); // Returns true (16 is 4^2) - * const result2 = isPowerOfFour(5); // Returns false (5 is not a power of four) + * isPowerOfFour(16) // true (16 = 4^2) + * isPowerOfFour(5) // false */ export const isPowerOfFour = (n: number): boolean => - n > 0 && (n & (n - 1)) === 0 && n % 3 === 1 + n > 0 && (n & (n - 1)) === 0 && n % 3 === 1 \ No newline at end of file diff --git a/bit_manipulation/log_two.ts b/bit_manipulation/log_two.ts index 7246c8ce..30a10625 100644 --- a/bit_manipulation/log_two.ts +++ b/bit_manipulation/log_two.ts @@ -1,15 +1,26 @@ /** + * Approximate base-2 logarithm using bitwise operators. + * + * Returns floor(log2(n)) for positive integers n. Throws a RangeError for n <= 0. + * * @author dev-madhurendra * @see https://handwiki.org/wiki/Binary_logarithm - * Approximate log2 using bitwise operators - * @param {number} n - * @returns {number} Log2 approximation equal to floor(log2(n)) + * @param n - Positive integer input. + * @returns floor(log2(n)). + * @throws RangeError if n <= 0. */ export const logTwo = (n: number): number => { + if (n <= 0) { + throw new RangeError('logTwo is only defined for positive integers.') + } + + let x = n let result = 0 - while (n >> 1) { - n >>= 1 + + while (x >> 1) { + x >>= 1 result++ } + return result -} +} \ No newline at end of file