diff --git a/base/complex.jl b/base/complex.jl index 49ac018096144..1e97844381d79 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -541,6 +541,40 @@ function cis(z::Complex) Complex(v * c, v * s) end +cispi(sign::Bool) = sign ? -1 : 1 +cispi(sign::Integer) = oftype(sign, cispi(isodd(sign))) +cispi(theta::Real) = Complex(cospi(theta), sinpi(theta)) + +""" + cispi(z) + +Return ``\\exp(iπz)``. + +This function also accepts integer or boolean arguments, and then +returns integer results. This allows calculating ``(-1)^s`` +conveniently and efficiently. + +`cispi` is related to [`signbit`](@ref), and allows decomposing +integers into sign bit and absolute value: ``cispi(signbit(n)) * +abs(n) == n``. For boolean values, it is also, ``signbit(cispi(b)) == +b``. + +# Examples +```jldoctest +julia> cispi(1) == -1 +true + +julia> cispi(0) == 1 +true +``` + +!!! compat "Julia 1.6" + This function requires Julia 1.6 or later. +""" +function cispi(z::Complex) + cospi(z) + im*sinpi(z) +end + """ angle(z) diff --git a/base/exports.jl b/base/exports.jl index 316025db9ce6c..d6b9a5c8b0b4e 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -226,6 +226,7 @@ export cbrt, ceil, cis, + cispi, clamp, cld, cmp, diff --git a/base/number.jl b/base/number.jl index 9b615c99d4147..bb5a39f533d48 100644 --- a/base/number.jl +++ b/base/number.jl @@ -92,6 +92,11 @@ copy(x::Number) = x # some code treats numbers as collection-like Returns `true` if the value of the sign of `x` is negative, otherwise `false`. +Related to `signbit` is [`cispi`](@ref) (which calculates `(-1)^n`). +This allows decomposing integers into sign bit and absolute value: +``cispi(signbit(n)) * abs(n) == n``. For boolean values, it is also, +``signbit(cispi(b)) == b``. + # Examples ```jldoctest julia> signbit(-4) diff --git a/doc/src/base/math.md b/doc/src/base/math.md index 511e2e6207fc4..787ea37796a4d 100644 --- a/doc/src/base/math.md +++ b/doc/src/base/math.md @@ -161,6 +161,7 @@ Base.reim Base.conj Base.angle Base.cis +Base.cispi Base.binomial Base.factorial Base.gcd diff --git a/test/complex.jl b/test/complex.jl index 0f419539a7027..9aede4c37c02f 100644 --- a/test/complex.jl +++ b/test/complex.jl @@ -123,6 +123,8 @@ end @test atanh(x) ≈ atanh(big(x)) @test cis(real(x)) ≈ cis(real(big(x))) @test cis(x) ≈ cis(big(x)) + @test cispi(real(x)) ≈ cispi(real(big(x))) + @test cispi(x) ≈ cispi(big(x)) @test cos(x) ≈ cos(big(x)) @test cosh(x) ≈ cosh(big(x)) @test exp(x) ≈ exp(big(x)) @@ -918,6 +920,21 @@ end @test cis(1.0+0.0im) ≈ 0.54030230586813971740093660744297660373231042061+0.84147098480789650665250232163029899962256306079im @test cis(pi) ≈ -1.0+0.0im @test cis(pi/2) ≈ 0.0+1.0im + @test cispi(false) == 1 + @test cispi(true) == -1 + @test cispi(-1) == -1 + @test cispi(0) == 1 + @test cispi(1) == -1 + @test cispi(2) == 1 + @test cispi(0.0) == cispi(0) + @test cispi(1.0) == cispi(1) + @test cispi(2.0) == cispi(2) + @test cispi(0.5) == im + @test cispi(1.5) == -im + @test cispi(0.25) ≈ cis(π/4) + @test cispi(0.0+0.0im) == cispi(0) + @test cispi(1.0+0.0im) == cispi(1) + @test cispi(2.0+0.0im) == cispi(2) end @testset "exp2" begin