Skip to content

Commit ab06131

Browse files
authored
merge: Improved Pow function (TheAlgorithms#911)
* feat: add negative power option * docs: add js doc for powOn function * feat: add PowFaster with faster algorithm, complexity O(logN) * chore: rename to exponent * chore: rename fixed * style: formated with standard
1 parent e8de031 commit ab06131

File tree

2 files changed

+87
-10
lines changed

2 files changed

+87
-10
lines changed

Maths/Pow.js

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,62 @@
1-
// Returns the value of x to the power of y
1+
/**
2+
* @function powLinear
3+
* @description - The powLinear function is a power function with Linear O(n) complexity
4+
* @param {number} base
5+
* @param {number} exponent
6+
* @returns {number}
7+
* @example - powLinear(2, 2) => 4 --> 2 * 2
8+
* @example - powLinear(3, 3) => 27 --> 3 * 3
9+
*/
10+
const powLinear = (base, exponent) => {
11+
if (exponent < 0) {
12+
base = 1 / base
13+
exponent = -exponent
14+
}
215

3-
const pow = (x, y) => {
416
let result = 1
5-
for (let i = 1; i <= y; i++) {
6-
result *= x
17+
18+
while (exponent--) { // Break the execution while the exponent will 0
19+
result *= base
720
}
21+
822
return result
923
}
1024

11-
export { pow }
25+
/**
26+
* @function powFaster
27+
* @description - The powFaster function is a power function with O(logN) complexity
28+
* @param {number} base
29+
* @param {number} exponent
30+
* @returns {number}
31+
* @example - powFaster(2, 2) => 4 --> 2 * 2
32+
* @example - powFaster(3, 3) => 27 --> 3 * 3
33+
*/
34+
const powFaster = (base, exponent) => {
35+
if (exponent < 2) { // explanation below - 1
36+
return base && ([1, base][exponent] || powFaster(1 / base, -exponent))
37+
}
38+
39+
if (exponent & 1) { // if the existing exponent is odd
40+
return base * powFaster(base * base, exponent >> 1) // explanation below - 2
41+
}
42+
43+
return powFaster(base * base, exponent / 2)
44+
}
45+
46+
/**
47+
* 1 - Magic of short circuit evaluation (&&, ||)
48+
* if the base is 0 then it returns 0 cause 0 is falsy
49+
* if the base is not 0 then it's must be truthy. after that, it will be executed the right portion of the && (AND) operator
50+
* Now it checks the exponent by the help array index, is it 0 or 1.
51+
* if the exponent is not 0 or 1 it's definitely less than 0, and a negative number is not a valid index number so it returns "undefined"
52+
* if the expression is undefined mean -> falsy, the || (OR) operator evaluates the right portion that is a recursive function.
53+
*/
54+
55+
/**
56+
* 2 - Play with right shift bitwise operator (>>)
57+
* right shift with any odd numbers it returns the floor number instead of float.
58+
* E.g. if the number is 5, after right shifting with 1 it's will give us 2, not 2.5
59+
* cause the right shift formula is --> x >> y = |x| / 2^y
60+
*/
61+
62+
export { powLinear, powFaster }

Maths/test/Pow.test.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
1-
import { pow } from '../Pow'
1+
import { powLinear, powFaster } from '../Pow'
22

3-
describe('Pow', () => {
3+
describe('Testing powLinear function', () => {
44
it('should return 1 for numbers with exponent 0', () => {
5-
expect(pow(2, 0)).toBe(1)
5+
expect(powLinear(2, 0)).toBe(1)
6+
})
7+
8+
it('should return 0.5 for numbers with exponent -1', () => {
9+
expect(powLinear(2, -1)).toBe(0.5)
10+
})
11+
12+
it('should return 0 for numbers with base 0', () => {
13+
expect(powLinear(0, 23)).toBe(0)
14+
})
15+
16+
it('should return the base to the exponent power', () => {
17+
expect(powLinear(24, 4)).toBe(331776)
18+
})
19+
})
20+
21+
describe('Testing powFaster function', () => {
22+
it('should return 1 for numbers with exponent 0', () => {
23+
expect(powFaster(2, 0)).toBe(1)
24+
})
25+
26+
it('should return 0.5 for numbers with exponent -1', () => {
27+
expect(powFaster(2, -1)).toBe(0.5)
628
})
729

830
it('should return 0 for numbers with base 0', () => {
9-
expect(pow(0, 23)).toBe(0)
31+
expect(powFaster(0, 23)).toBe(0)
1032
})
1133

1234
it('should return the base to the exponent power', () => {
13-
expect(pow(24, 4)).toBe(331776)
35+
expect(powFaster(24, 4)).toBe(331776)
36+
})
37+
38+
it('should return the result in O(lonN) complexity', () => {
39+
expect(powFaster(2, 64)).toBe(18446744073709552000) // execution time Math.log2(64) -> 6
1440
})
1541
})

0 commit comments

Comments
 (0)