diff --git a/src/math/Math.jl b/src/math/Math.jl index f8c1eb0a..ed5ec2bd 100644 --- a/src/math/Math.jl +++ b/src/math/Math.jl @@ -36,6 +36,7 @@ export combination export divisors export eratosthenes export euler_method +export exp_logn export is_mersenne_prime export totient export factorial_iterative @@ -101,6 +102,7 @@ include("combination.jl") include("divisors.jl") include("euler_method.jl") include("eulers_totient.jl") +include("exp_logn.jl") include("factorial.jl") include("fibonacci.jl") include("floor.jl") diff --git a/src/math/exp_logn.jl b/src/math/exp_logn.jl new file mode 100644 index 00000000..fb4b8fa1 --- /dev/null +++ b/src/math/exp_logn.jl @@ -0,0 +1,59 @@ +""" + exp_logn(x::Number, n::Int) + +Recursive function which calculates 'x' to the power of 'n' in O(log n) complexity. + +# Arguments: +- `x` : Base +- `n` : Exponent + +# Examples/Tests +```julia +exp_logn(0, 5) # returns 0 +exp_logn(3.14, 0) # returns 1 +exp_logn(2, 5) # returns 32 +exp_logn(2, -2) # returns 0.25 +exp_logn(2, -5) # returns 0.03125 +``` + +# Implementation +```julia +function exp_logn(x::Number, n::Int) + if n == 0 + return 1 + elseif n < 0 + return 1/exp_logn(x, -n) + else + tmp = exp_logn(x, div(n,2)) + + if n%2 == 0 + # If n is even, x^n = x^(n/2) * x^(n/2) + return tmp * tmp + else + # else, x^n = x^(n/2) * x^(n/2) * x + return tmp * tmp * x + end + end +end +``` + +Contributed by [Nikola Mircic](https://www.github.com/Nikola-Mircic) +""" + +function exp_logn(x::Number, n::Int) + if n == 0 + return 1 + elseif n < 0 + return 1/exp_logn(x, -n) + else + tmp = exp_logn(x, div(n,2)) + + if n%2 == 0 + # If n is even, x^n = x^(n/2) * x^(n/2) + return tmp * tmp + else + # else, x^n = x^(n/2) * x^(n/2) * x + return tmp * tmp * x + end + end +end diff --git a/test/math.jl b/test/math.jl index ce6b5ab6..539aa0fd 100644 --- a/test/math.jl +++ b/test/math.jl @@ -239,6 +239,14 @@ using TheAlgorithms.Math @test_throws DomainError totient(-1) end + @testset "Math: Exponentiation in O(log n)" begin + @test exp_logn(0, 5) == 0 + @test exp_logn(3.14, 0) == 1 + @test exp_logn(2, 5) == 32 + @test exp_logn(2, -2) == 0.25 + @test exp_logn(2, -5) == 0.03125 + end + @testset "Math: Factorial Related" begin @test factorial_iterative(5) == 120 @test factorial_iterative(0) == 1