Skip to content

Commit

Permalink
Convert methods for other common complex types available
Browse files Browse the repository at this point in the history
These methods were written in order to avoid having to use real()
or imag(), as they create a new MPFRFloat object.
  • Loading branch information
andrioni committed May 3, 2013
1 parent cd20424 commit 2d23952
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
40 changes: 36 additions & 4 deletions base/mpc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,34 @@ convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x)
convert{N,P}(::Type{MPCComplex{N,P}}, x::ImaginaryUnit) = MPCComplex(x)
convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x)

convert(::Type{Float64}, x::MPCComplex) = ccall((:mpc_get_d,:libmpc), Float64, (Ptr{mpc_struct},), &(x.mpc))
convert(::Type{Float32}, x::MPCComplex) = ccall((:mpc_get_flt,:libmpc), Float32, (Ptr{mpc_struct},), &(x.mpc))
#convert(::Type{FloatingPoint}, x::BigInt) = MPCComplex(x)

function convert(::Type{Complex{Float64}}, x::MPCComplex)
return complex(
ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(realref(x))),
ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(imagref(x))))
end
function convert(::Type{Complex{Float32}}, x::MPCComplex)
return complex(
ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(realref(x))),
ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(imagref(x))))
end
function convert(::Type{Complex{Int64}}, x::MPCComplex)
if realint(x) && imagint(x)
return complex(
ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end]),
ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end]))
else
throw(InexactError())
end
end
function convert(::Type{Complex{Int32}}, x::MPCComplex)
if realint(x) && imagint(x)
return complex(
int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end])),
int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end])))
else
throw(InexactError())
end
end
promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P}
promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{T}) = MPCComplex
promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{Complex{T}}) = MPCComplex{N,P}
Expand Down Expand Up @@ -267,4 +291,12 @@ string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im"
show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision")
showcompact(io::IO, b::MPCComplex) = print(io, string(b))

# Internal functions
# Unsafe for general use
realref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.reprec, x.mpc.resign, x.mpc.reexp, x.mpc.red)
imagref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.imprec, x.mpc.imsign, x.mpc.imexp, x.mpc.imd)
realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0
imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0


end #module
13 changes: 13 additions & 0 deletions test/mpc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ y = MPCComplex(x)
@test real(x) == real(y)
@test imag(x) == imag(y)

# conversion
with_bigcomplex_precision(53) do
x = MPCComplex(12, 42)
@test typeof(convert(Complex{Float64}, x)) == Complex{Float64}
@test typeof(convert(Complex{Float32}, x)) == Complex{Float32}
@test typeof(convert(Complex{Int64}, x)) == Complex{Int64}
@test typeof(convert(Complex{Int32}, x)) == Complex{Int32}
@test 12. + 42.0im == convert(Complex{Float64}, x)
@test 12f0 + 42f0im == convert(Complex{Float32}, x)
@test 12 + 42im == convert(Complex{Int64}, x)
@test 12 + 42im == convert(Complex{Int32}, x)
end

# +
x = MPCComplex(12,42)
@test (x + x) == MPCComplex(24, 84)
Expand Down

0 comments on commit 2d23952

Please sign in to comment.