Skip to content

Commit

Permalink
add conversions from float to BigInt. ref JuliaLang#6183
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Mar 17, 2014
1 parent 1153064 commit 13d621a
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
12 changes: 11 additions & 1 deletion base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,21 @@ function BigInt(x::Union(Clong,Int32))
end
function BigInt(x::Union(Culong,Uint32))
z = BigInt()
ccall((:__gmpz_set_ui, :libgmp), Void,(Ptr{BigInt}, Culong), &z, x)
ccall((:__gmpz_set_ui, :libgmp), Void, (Ptr{BigInt}, Culong), &z, x)
return z
end

BigInt(x::Bool) = BigInt(uint(x))

function BigInt(x::Float64)
!isinteger(x) && throw(InexactError())
z = BigInt()
ccall((:__gmpz_set_d, :libgmp), Void, (Ptr{BigInt}, Cdouble), &z, x)
return z
end

BigInt(x::Union(Float16,Float32)) = BigInt(float64(x))

function BigInt(x::Integer)
if x < 0
if typemin(Clong) <= x
Expand Down Expand Up @@ -94,6 +103,7 @@ function BigInt(x::Integer)
end

convert(::Type{BigInt}, x::Integer) = BigInt(x)
convert(::Type{BigInt}, x::FloatingPoint) = BigInt(x)

function convert(::Type{Int64}, x::BigInt)
lo = int64(convert(Culong, x & typemax(Uint32)))
Expand Down
12 changes: 4 additions & 8 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,11 @@ BigFloat(x::Integer) = BigFloat(BigInt(x))
BigFloat(x::Union(Bool,Int8,Int16,Int32)) = BigFloat(convert(Clong,x))
BigFloat(x::Union(Uint8,Uint16,Uint32)) = BigFloat(convert(Culong,x))

BigFloat(x::Union(Float16,Float32,Float16)) = BigFloat(float64(x))
BigFloat(x::Union(Float16,Float32)) = BigFloat(float64(x))
BigFloat(x::Rational) = BigFloat(num(x)) / BigFloat(den(x))

convert(::Type{Rational}, x::BigFloat) = convert(Rational{BigInt}, x)
convert(::Type{BigFloat}, x::Rational) = BigFloat(x) # to resolve ambiguity
convert(::Type{BigFloat}, x::Float16) = BigFloat(x) # to resolve ambiguity
convert(::Type{BigFloat}, x::Real) = BigFloat(x)
convert(::Type{FloatingPoint}, x::BigInt) = BigFloat(x)

Expand All @@ -107,12 +106,9 @@ for to in (Uint8, Uint16, Uint32, Uint64)
end
end

function convert(::Type{BigInt}, x::BigFloat)
if isinteger(x)
return itrunc(x)
else
throw(InexactError())
end
function Base.BigInt(x::BigFloat)
!isinteger(x) && throw(InexactError())
return itrunc(x)
end
convert(::Type{Float64}, x::BigFloat) =
ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{BigFloat},Int32), &x, ROUNDING_MODE[end])
Expand Down
5 changes: 5 additions & 0 deletions test/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,8 @@ ndigits_mismatch(n) = ndigits(n) != ndigits(BigInt(n))
@test !any(ndigits_mismatch, 64:99)
@test !any(ndigits_mismatch, 512:999)
@test !any(ndigits_mismatch, 8192:9999)

# conversion from float
@test BigInt(2.0) == BigInt(2.0f0) == BigInt(big(2.0)) == 2
@test_throws convert(BigInt, 2.1)
@test_throws convert(BigInt, big(2.1))

0 comments on commit 13d621a

Please sign in to comment.