Repository: JuliaLang/julia
File: test/complex.jl (Julia)

Code before:
        @test typeof(sign(z)) == typeof(z)
    end
    for T in (Int32, Int64)
        z = Complex{T}(1)
        @test typeof(sign(z)) == typeof(float(z))
        z = Complex{T}(0)
        @test typeof(sign(z)) == typeof(float(z))
    end

    @test sign(0 + 0im) == 0
    @test sign(2 + 0im) == 1
    @test sign(-2 + 0im) == -1
    @test sign(1 + im) ≈ (1 + im) / sqrt(2)
    @test sign(1 - im) ≈ (1 - im) / sqrt(2)

    for T in (Float16, Float32, Float64)
        z = Complex(zero(T), zero(T))
        @test sign(z) === z
        @test sign(-z) === -z
        @test sign(conj(z)) === conj(z)
        @test sign(-conj(z)) === -conj(z)
    end
end

@testset "eps" begin
    @test eps(1.0+1.0im) == 3.1401849173675503e-16
    @test eps(Complex128) == eps(1.0+1.0im)
    @test eps(Complex64) == 1.1920929f-7
    @test eps(Float32(1.0)+Float32(1.0)im) == eps(Complex{Float32})
end

@testset "cis" begin
    @test cis(0.0+1.0im) ≈ 0.367879441171442321595523770161460867445811131031767834507836+0.0im
    @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
end

@testset "exp2" begin
    @test exp2(0.0+0.0im) == 1.0+0.0im
    @test exp2(1.0+0.0im) == 2.0+0.0im
    #wolframalpha
    @test exp2(1.0+3.0im) ≈ -0.9739888359315627962096198412+1.74681016354974281701922im
end

@testset "exp10" begin
    @test exp10(0.0+0.0im) == 1.0+0.0im
    @test exp10(1.0+0.0im) == 10.0+0.0im
    #wolframalpha
    @test exp10(1.0+2.0im) ≈ -1.0701348355877020772086517528518239460495529361-9.9425756941378968736161937190915602112878340717im
end

Review comment (suggestion):
might be better to use `===` to also test the types on the  lhs == rhs 

Code after:

@test complex.(1.0, [1.0, 1.0]) == [complex(1.0, 1.0), complex(1.0, 1.0)]
@test complex.([1.0, 1.0], 1.0) == [complex(1.0, 1.0), complex(1.0, 1.0)]
# robust division of Float64
# hard complex divisions from Fig 6 of arxiv.1210.4539
z7 = ComplexF64(3.898125604559113300e289, 8.174961907852353577e295)
z9 = ComplexF64(0.001953125, -0.001953125)
z10 = ComplexF64( 1.02951151789360578e-84, 6.97145987515076231e-220)
harddivs = ((1.0+im*1.0, 1.0+im*2^1023.0, 2^-1023.0-im*2^-1023.0), #1
      (1.0+im*1.0, 2^-1023.0+im*2^-1023.0, 2^1023.0+im*0.0), #2
      (2^1023.0+im*2^-1023.0, 2^677.0+im*2^-677.0, 2^346.0-im*2^-1008.0), #3
      (2^1023.0+im*2^1023.0, 1.0+im*1.0, 2^1023.0+im*0.0), #4
      (2^1020.0+im*2^-844., 2^656.0+im*2^-780.0, 2^364.0-im*2^-1072.0), #5
      (2^-71.0+im*2^1021., 2^1001.0+im*2^-323.0, 2^-1072.0+im*2^20.0), #6
      (2^-347.0+im*2^-54., 2^-1037.0+im*2^-1058.0, z7), #7
      (2^-1074.0+im*2^-1074., 2^-1073.0+im*2^-1074., 0.6+im*0.2), #8
      (2^1015.0+im*2^-989., 2^1023.0+im*2^1023.0, z9), #9
      (2^-622.0+im*2^-1071., 2^-343.0+im*2^-798.0, z10) #10
      )

# calculate "accurate bits" in range 0:53 by algorithm given in arxiv.1210.4539
function sb_accuracy(x,expected)
    min(logacc(real(x),real(expected)),
        logacc(imag(x),imag(expected)))
end
relacc(x,expected) = abs(x-expected)/abs(expected)
function logacc(x::Float64,expected::Float64)
    x == expected && (return 53)
    expected == 0 && (return 0)
    (x == Inf || x == -Inf) && (return 0)
    isnan(x) && (return 0)
    ra = relacc(BigFloat(x),BigFloat(expected))
    max(floor(Int,-log2(ra)),0)
end
# the robust division algorithm should have 53 or 52
# bits accuracy for each of the hard divisions
@test 52 <= minimum([sb_accuracy(h[1]/h[2],h[3]) for h in harddivs])

# division of non-Float64
function cdiv_test(a,b)
    c=convert(ComplexF64,a)/convert(ComplexF64,b)
    50 <= sb_accuracy(c,convert(ComplexF64,a/b))
end
@test cdiv_test(complex(1//2, 3//4), complex(17//13, 4//5))
@test cdiv_test(complex(1,2), complex(8997,2432))

@testset "inv" begin
    @test inv(1e300+0im) == 1e-300 - 0.0im
    @test inv(0+1e300im) == 0.0 - 1e-300im
end