diff --git a/Maths/IsPowerOfTwo.js b/Maths/IsPowerOfTwo.js new file mode 100644 index 0000000000..aee1cd7767 --- /dev/null +++ b/Maths/IsPowerOfTwo.js @@ -0,0 +1,20 @@ +/** + * @function isPowerOfTwo + * @description Checks whether a given positive integer is a power of two. + * A number is a power of two if it can be expressed as 2^n where n + * is a non-negative integer. Uses bitwise AND for efficient checking. + * @param {number} n - A positive integer + * @returns {boolean} - True if n is a power of two, false otherwise + * @see https://en.wikipedia.org/wiki/Power_of_two + * @example isPowerOfTwo(1) => true + * @example isPowerOfTwo(16) => true + * @example isPowerOfTwo(18) => false + */ +const isPowerOfTwo = (n) => { + if (!Number.isInteger(n) || n < 1) { + throw new TypeError('Input must be a positive integer') + } + return (n & (n - 1)) === 0 +} + +export { isPowerOfTwo } diff --git a/Maths/test/IsPowerOfTwo.test.js b/Maths/test/IsPowerOfTwo.test.js new file mode 100644 index 0000000000..291b1482ab --- /dev/null +++ b/Maths/test/IsPowerOfTwo.test.js @@ -0,0 +1,47 @@ +import { isPowerOfTwo } from '../IsPowerOfTwo.js' + +describe('isPowerOfTwo', () => { + test('1 is a power of two (2^0)', () => { + expect(isPowerOfTwo(1)).toBe(true) + }) + + test('2 is a power of two (2^1)', () => { + expect(isPowerOfTwo(2)).toBe(true) + }) + + test('4 is a power of two (2^2)', () => { + expect(isPowerOfTwo(4)).toBe(true) + }) + + test('16 is a power of two (2^4)', () => { + expect(isPowerOfTwo(16)).toBe(true) + }) + + test('1024 is a power of two (2^10)', () => { + expect(isPowerOfTwo(1024)).toBe(true) + }) + + test('3 is NOT a power of two', () => { + expect(isPowerOfTwo(3)).toBe(false) + }) + + test('18 is NOT a power of two', () => { + expect(isPowerOfTwo(18)).toBe(false) + }) + + test('100 is NOT a power of two', () => { + expect(isPowerOfTwo(100)).toBe(false) + }) + + test('throws TypeError for zero', () => { + expect(() => isPowerOfTwo(0)).toThrow(TypeError) + }) + + test('throws TypeError for negative input', () => { + expect(() => isPowerOfTwo(-4)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => isPowerOfTwo(4.5)).toThrow(TypeError) + }) +})