Skip to content

Commit

Permalink
use parse for BigFloat/BigInt
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyrne committed Apr 24, 2015
1 parent 7e63e6a commit d9a9cc4
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 98 deletions.
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,6 @@ export float32_isvalid, float64_isvalid
@deprecate parseint(T::Type, s, base) parse(T, s, base)

@deprecate linrange linspace

@deprecate BigFloat(s::AbstractString) parse(BigFloat,s)
@deprecate BigInt(s::AbstractString) parse(BigInt,s)
1 change: 0 additions & 1 deletion base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ widen(::Type{BigInt}) = BigInt
signed(x::BigInt) = x

BigInt(x::BigInt) = x
BigInt(s::AbstractString) = parse(BigInt,s)

function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base::Int, raise::Bool)
_n = Nullable{BigInt}()
Expand Down
32 changes: 22 additions & 10 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ export
BigFloat,
get_bigfloat_precision,
set_bigfloat_precision,
with_bigfloat_precision
with_bigfloat_precision,
bigfloat_str,
big_str

import
Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, bessely,
Expand All @@ -18,7 +20,7 @@ import
cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2,
serialize, deserialize, cbrt, typemax, typemin, unsafe_trunc,
realmin, realmax, get_rounding, set_rounding, maxintfloat, widen,
significand, frexp
significand, frexp, tryparse

import Base.Rounding: get_rounding_raw, set_rounding_raw

Expand Down Expand Up @@ -77,14 +79,6 @@ function BigFloat(x::BigInt)
return z
end

function BigFloat(x::AbstractString, base::Int)
z = BigFloat()
err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{UInt8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end])
err == 0 || throw("incorrectly formatted number \"$x\"")
return z
end
BigFloat(x::AbstractString) = BigFloat(x, 10)

BigFloat(x::Integer) = BigFloat(BigInt(x))

BigFloat(x::Union(Bool,Int8,Int16,Int32)) = BigFloat(convert(Clong,x))
Expand All @@ -93,6 +87,24 @@ BigFloat(x::Union(UInt8,UInt16,UInt32)) = BigFloat(convert(Culong,x))
BigFloat(x::Union(Float16,Float32)) = BigFloat(Float64(x))
BigFloat(x::Rational) = BigFloat(num(x)) / BigFloat(den(x))

function tryparse(::Type{BigFloat}, s::AbstractString, base::Int=0)
z = BigFloat()
err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{UInt8}, Int32, Int32), &z, s, base, ROUNDING_MODE[end])
err == 0 ? Nullable(z) : Nullable{BigFloat}()
end

macro bigfloat_str(s)
parse(BigFloat,s)
end

macro big_str(s)
n = tryparse(BigInt,s)
!isnull(n) && return get(n)
n = tryparse(BigFloat,s)
!isnull(n) && return get(n)
throw(ArgumentError("invalid number format $(repr(s)) for BigInt or BigFloat"))
end

convert(::Type{Rational}, x::BigFloat) = convert(Rational{BigInt}, x)
convert{S}(::Type{BigFloat}, x::Rational{S}) = BigFloat(x) # to resolve ambiguity
convert(::Type{BigFloat}, x::Real) = BigFloat(x)
Expand Down
2 changes: 1 addition & 1 deletion base/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1632,7 +1632,7 @@ tryparse(::Type{Float64}, s::SubString) = ccall(:jl_try_substrtod, Nullable{Floa
tryparse(::Type{Float32}, s::AbstractString) = ccall(:jl_try_strtof, Nullable{Float32}, (Ptr{UInt8},), s)
tryparse(::Type{Float32}, s::SubString) = ccall(:jl_try_substrtof, Nullable{Float32}, (Ptr{UInt8},Csize_t,Cint), s.string, s.offset, s.endof)

function parse{T<:Union(Float32,Float64)}(::Type{T}, s::AbstractString)
function parse{T<:FloatingPoint}(::Type{T}, s::AbstractString)
nf = tryparse(T, s)
isnull(nf) ? throw(ArgumentError("invalid number format $(repr(s)) for $T")) : get(nf)
end
Expand Down
92 changes: 46 additions & 46 deletions test/bigint.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
a = BigInt("123456789012345678901234567890")
b = BigInt("123456789012345678901234567891")
a = parse(BigInt,"123456789012345678901234567890")
b = parse(BigInt,"123456789012345678901234567891")

@test typeof(a+1) == BigInt
@test a+1 == b
Expand All @@ -11,20 +11,20 @@ b = BigInt("123456789012345678901234567891")
@test !(b < a)
@test !(b <= a)

c = BigInt("246913578024691357802469135780")
c = parse(BigInt,"246913578024691357802469135780")
@test typeof(a * 2) == BigInt
@test a*2 == c
@test c-a == a
@test c == a + a
@test c+1 == a+b

d = BigInt("-246913578024691357802469135780")
d = parse(BigInt,"-246913578024691357802469135780")
@test typeof(d) == BigInt
@test d == -c

ee = typemax(Int64)
@test typeof(BigInt(ee)) == BigInt
@test BigInt(ee)+1 == BigInt("9223372036854775808")
@test BigInt(ee)+1 == parse(BigInt,"9223372036854775808")

#Multiple calls for sanity check, since we're doing direct memory manipulation
@test string(a) == "123456789012345678901234567890"
Expand Down Expand Up @@ -163,58 +163,58 @@ end
@test gcd(BigInt(48), BigInt(180)) == 12
@test lcm(BigInt(48), BigInt(180)) == 720

@test factorial(BigInt(40)) == BigInt("815915283247897734345611269596115894272000000000")
@test factorial(BigInt(40)) == parse(BigInt,"815915283247897734345611269596115894272000000000")
@test binomial(BigInt(1), -1) == BigInt(0)
@test binomial(BigInt(1), 2) == BigInt(0)
@test binomial(BigInt(-53), 42) == BigInt("959509335087854414441273718")
@test binomial(BigInt(113), BigInt(42)) == BigInt("18672199984318438125634054194360")
@test binomial(BigInt(-53), 42) == parse(BigInt,"959509335087854414441273718")
@test binomial(BigInt(113), BigInt(42)) == parse(BigInt,"18672199984318438125634054194360")

a = rand(1:100, 10000)
b = map(BigInt, a)
@test sum(a) == sum(b)

# Iterated arithmetic
a = BigInt("315135")
b = BigInt("12412")
c = BigInt("3426495623485904783478347")
d = BigInt("-1398984130")
f = BigInt("2413804710837418037418307081437315263635345357386985747464")
g = BigInt("-1")

@test +(a, b) == BigInt("327547")
@test +(a, b, c) == BigInt("3426495623485904783805894")
@test +(a, b, c, d) == BigInt("3426495623485903384821764")
@test +(a, b, c, d, f) == BigInt("2413804710837418037418307081437318690130968843290370569228")
@test +(a, b, c, d, f, g) == BigInt("2413804710837418037418307081437318690130968843290370569227")

@test *(a, b) == BigInt("3911455620")
@test *(a, b, c) == BigInt("13402585563389346256121263521460140")
@test *(a, b, c, d) == BigInt("-18750004504148804423388563022070650287578200")
@test *(a, b, c, d, f) == BigInt("-45258849200337190631492857400003938881995610529251881450243326128168934937055005474972396281351684800")
@test *(a, b, c, d, f, g) == BigInt("45258849200337190631492857400003938881995610529251881450243326128168934937055005474972396281351684800")

@test ($)(a, b) == BigInt("327299")
@test ($)(a, b, c) == BigInt("3426495623485904783798472")
@test ($)(a, b, c, d) == BigInt("-3426495623485906178489610")
@test ($)(a, b, c, d, f) == BigInt("-2413804710837418037418307081437316711364709261074607933698")
@test ($)(a, b, c, d, f, g) == BigInt("2413804710837418037418307081437316711364709261074607933697")

@test (&)(a, b) == BigInt("124")
@test (&)(a, b, c) == BigInt("72")
@test (&)(a, b, c, d) == BigInt("8")
@test (&)(a, b, c, d, f) == BigInt("8")
@test (&)(a, b, c, d, f, g) == BigInt("8")

@test (|)(a, b) == BigInt("327423")
@test (|)(a, b, c) == BigInt("3426495623485904783802111")
@test (|)(a, b, c, d) == BigInt("-1396834561")
@test (|)(a, b, c, d, f) == BigInt("-1358954753")
@test (|)(a, b, c, d, f, g) == BigInt("-1")
a = parse(BigInt,"315135")
b = parse(BigInt,"12412")
c = parse(BigInt,"3426495623485904783478347")
d = parse(BigInt,"-1398984130")
f = parse(BigInt,"2413804710837418037418307081437315263635345357386985747464")
g = parse(BigInt,"-1")

@test +(a, b) == parse(BigInt,"327547")
@test +(a, b, c) == parse(BigInt,"3426495623485904783805894")
@test +(a, b, c, d) == parse(BigInt,"3426495623485903384821764")
@test +(a, b, c, d, f) == parse(BigInt,"2413804710837418037418307081437318690130968843290370569228")
@test +(a, b, c, d, f, g) == parse(BigInt,"2413804710837418037418307081437318690130968843290370569227")

@test *(a, b) == parse(BigInt,"3911455620")
@test *(a, b, c) == parse(BigInt,"13402585563389346256121263521460140")
@test *(a, b, c, d) == parse(BigInt,"-18750004504148804423388563022070650287578200")
@test *(a, b, c, d, f) == parse(BigInt,"-45258849200337190631492857400003938881995610529251881450243326128168934937055005474972396281351684800")
@test *(a, b, c, d, f, g) == parse(BigInt,"45258849200337190631492857400003938881995610529251881450243326128168934937055005474972396281351684800")

@test ($)(a, b) == parse(BigInt,"327299")
@test ($)(a, b, c) == parse(BigInt,"3426495623485904783798472")
@test ($)(a, b, c, d) == parse(BigInt,"-3426495623485906178489610")
@test ($)(a, b, c, d, f) == parse(BigInt,"-2413804710837418037418307081437316711364709261074607933698")
@test ($)(a, b, c, d, f, g) == parse(BigInt,"2413804710837418037418307081437316711364709261074607933697")

@test (&)(a, b) == parse(BigInt,"124")
@test (&)(a, b, c) == parse(BigInt,"72")
@test (&)(a, b, c, d) == parse(BigInt,"8")
@test (&)(a, b, c, d, f) == parse(BigInt,"8")
@test (&)(a, b, c, d, f, g) == parse(BigInt,"8")

@test (|)(a, b) == parse(BigInt,"327423")
@test (|)(a, b, c) == parse(BigInt,"3426495623485904783802111")
@test (|)(a, b, c, d) == parse(BigInt,"-1396834561")
@test (|)(a, b, c, d, f) == parse(BigInt,"-1358954753")
@test (|)(a, b, c, d, f, g) == parse(BigInt,"-1")

@test isprime(BigInt(1000000007))
@test isprime(BigInt(1000000007), 1)
@test isprime(BigInt(10000000019))
@test isprime(BigInt("359334085968622831041960188598043661065388726959079837"))
@test isprime(parse(BigInt,"359334085968622831041960188598043661065388726959079837"))
@test !isprime(BigInt(1))
@test !isprime(BigInt(10000000020))

Expand Down Expand Up @@ -258,7 +258,7 @@ s = string(n)

# serialization (#5133)
let
n = BigInt("359334085968622831041960188598043661065388726959079837")
n = parse(BigInt,"359334085968622831041960188598043661065388726959079837")
b = IOBuffer()
serialize(b,n)
seek(b,0)
Expand Down
68 changes: 34 additions & 34 deletions test/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ y = BigFloat(BigInt(12))
@test_approx_eq x y
y = BigFloat(BigFloat(12))
@test_approx_eq x y
y = BigFloat("12")
y = parse(BigFloat,"12")
@test_approx_eq x y
y = BigFloat(Float32(12.))
@test_approx_eq x y
Expand Down Expand Up @@ -64,11 +64,11 @@ g = BigFloat(0.03125)
@test +(a, b, c, d, f) == BigFloat(17.6875)
@test +(a, b, c, d, f, g) == BigFloat(17.71875)

@test *(a, b) == BigFloat("2.8328125e+02")
@test *(a, b, c) == BigFloat("-1.98296875e+03")
@test *(a, b, c, d) == BigFloat("2.52828515625e+04")
@test *(a, b, c, d, f) == BigFloat("5.214588134765625e+04")
@test *(a, b, c, d, f, g) == BigFloat("1.6295587921142578125e+03")
@test *(a, b) == parse(BigFloat,"2.8328125e+02")
@test *(a, b, c) == parse(BigFloat,"-1.98296875e+03")
@test *(a, b, c, d) == parse(BigFloat,"2.52828515625e+04")
@test *(a, b, c, d, f) == parse(BigFloat,"5.214588134765625e+04")
@test *(a, b, c, d, f, g) == parse(BigFloat,"1.6295587921142578125e+03")

# < / > / <= / >=
x = BigFloat(12)
Expand All @@ -91,7 +91,7 @@ z = BigFloat(30)
with_bigfloat_precision(4) do
# default mode is round to nearest
down, up = with_rounding(BigFloat,RoundNearest) do
BigFloat("0.0938"), BigFloat("0.102")
parse(BigFloat,"0.0938"), parse(BigFloat,"0.102")
end
with_rounding(BigFloat,RoundDown) do
@test BigFloat(0.1) == down
Expand Down Expand Up @@ -133,18 +133,18 @@ y = BigFloat(1)
@test isnan(y) == false

# convert to
@test convert(BigFloat, 1//2) == BigFloat("0.5")
@test convert(BigFloat, 1//2) == parse(BigFloat,"0.5")
@test typeof(convert(BigFloat, 1//2)) == BigFloat
@test convert(BigFloat, 0.5) == BigFloat("0.5")
@test convert(BigFloat, 0.5) == parse(BigFloat,"0.5")
@test typeof(convert(BigFloat, 0.5)) == BigFloat
@test convert(BigFloat, 40) == BigFloat("40")
@test convert(BigFloat, 40) == parse(BigFloat,"40")
@test typeof(convert(BigFloat, 40)) == BigFloat
@test convert(BigFloat, Float32(0.5)) == BigFloat("0.5")
@test convert(BigFloat, Float32(0.5)) == parse(BigFloat,"0.5")
@test typeof(convert(BigFloat, Float32(0.5))) == BigFloat
@test convert(BigFloat, BigInt("9223372036854775808")) == BigFloat("9223372036854775808")
@test typeof(convert(BigFloat, BigInt("9223372036854775808"))) == BigFloat
@test convert(FloatingPoint, BigInt("9223372036854775808")) == BigFloat("9223372036854775808")
@test typeof(convert(FloatingPoint, BigInt("9223372036854775808"))) == BigFloat
@test convert(BigFloat, parse(BigInt,"9223372036854775808")) == parse(BigFloat,"9223372036854775808")
@test typeof(convert(BigFloat, parse(BigInt,"9223372036854775808"))) == BigFloat
@test convert(FloatingPoint, parse(BigInt,"9223372036854775808")) == parse(BigFloat,"9223372036854775808")
@test typeof(convert(FloatingPoint, parse(BigInt,"9223372036854775808"))) == BigFloat

# convert from
@test convert(Float64, BigFloat(0.5)) == 0.5
Expand Down Expand Up @@ -349,9 +349,9 @@ y = BigFloat(42)
# round
x = BigFloat(42.42)
y = with_bigfloat_precision(256) do
BigFloat("9223372036854775809.2324")
parse(BigFloat,"9223372036854775809.2324")
end
z = BigInt("9223372036854775809")
z = parse(BigInt,"9223372036854775809")
@test round(Integer,x) == 42
@test round(Integer,y) == z
@test typeof(round(UInt8, x)) == UInt8 && round(UInt8, x) == 0x2a
Expand Down Expand Up @@ -447,12 +447,12 @@ with_bigfloat_precision(53) do
end

# ceil / floor / trunc
x = BigFloat("28273.7312487489135135135")
x = parse(BigFloat,"28273.7312487489135135135")
y = BigInt(28273)
z = BigInt(28274)
a = BigFloat("123456789012345678901234567890.2414")
b = BigInt("123456789012345678901234567890")
c = BigInt("123456789012345678901234567891")
a = parse(BigFloat,"123456789012345678901234567890.2414")
b = parse(BigInt,"123456789012345678901234567890")
c = parse(BigInt,"123456789012345678901234567891")
@test ceil(x) == z
@test typeof(ceil(x)) == BigFloat
@test floor(x) == y
Expand Down Expand Up @@ -547,8 +547,8 @@ c = BigInt("123456789012345678901234567891")

# basic arithmetic
# Signed addition
a = BigFloat("123456789012345678901234567890")
b = BigFloat("123456789012345678901234567891")
a = parse(BigFloat,"123456789012345678901234567890")
b = parse(BigFloat,"123456789012345678901234567891")
@test a+Int8(1) == b
@test a+Int16(1) == b
@test a+Int32(1) == b
Expand Down Expand Up @@ -669,10 +669,10 @@ b = BigFloat("123456789012345678901234567891")
@test BigInt(1) * a == a

# Signed division
c = BigInt("61728394506172839450617283945")
c = parse(BigInt,"61728394506172839450617283945")
# d = 2^200
d = BigFloat("1606938044258990275541962092341162602522202993782792835301376")
f = BigFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61")
d = parse(BigFloat,"1606938044258990275541962092341162602522202993782792835301376")
f = parse(BigFloat,"6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61")

@test a/Int8(2) == c
@test a/Int16(2) == c
Expand Down Expand Up @@ -715,8 +715,8 @@ f = BigFloat("6.2230152778611417071440640537801242405902521687211671331011166147
# old tests
tol = 1e-12

a = BigFloat("12.34567890121")
b = BigFloat("12.34567890122")
a = parse(BigFloat,"12.34567890121")
b = parse(BigFloat,"12.34567890122")

@test_approx_eq_eps a+1e-11 b tol
@test !(b == a)
Expand All @@ -725,13 +725,13 @@ b = BigFloat("12.34567890122")
@test !(b < a)
@test !(b <= a)

c = BigFloat("24.69135780242")
c = parse(BigFloat,"24.69135780242")
@test typeof(a * 2) == BigFloat
@test_approx_eq_eps a*2 c tol
@test_approx_eq_eps (c-a) a tol


d = BigFloat("-24.69135780242")
d = parse(BigFloat,"-24.69135780242")
@test typeof(d) == BigFloat
@test_approx_eq_eps d+c 0 tol

Expand Down Expand Up @@ -759,8 +759,8 @@ d = BigFloat("-24.69135780242")
@test typeof(BigFloat(1//1)) == BigFloat
@test typeof(BigFloat(one(Rational{BigInt}))) == BigFloat

f = BigFloat("1234567890.123")
g = BigFloat("1234567891.123")
f = parse(BigFloat,"1234567890.123")
g = parse(BigFloat,"1234567891.123")

tol = 1e-3

Expand Down Expand Up @@ -796,7 +796,7 @@ tol = 1e-3

# issue #3399
i1 = BigInt(10)^Int32(1000)
i2 = BigInt("10000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
i2 = parse(BigInt,"10000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
f = BigFloat(10)^Int32(1000)
@test i1 != i2
@test i1 != f
Expand All @@ -811,7 +811,7 @@ i3 = trunc(Integer,f)
@test i3+1 >= f

err(z, x) = abs(z - x) / abs(x)
@test 1e-60 > err(eta(BigFloat("1.005")), BigFloat("0.693945708117842473436705502427198307157819636785324430166786"))
@test 1e-60 > err(eta(parse(BigFloat,"1.005")), parse(BigFloat,"0.693945708117842473436705502427198307157819636785324430166786"))
@test 1e-60 > err(exp(eta(big(1.0))), 2.0)

# issue #8318
Expand Down
Loading

0 comments on commit d9a9cc4

Please sign in to comment.