Skip to content

Commit

Permalink
Merge pull request JuliaLang#10955 from JuliaLang/sb/big-parse
Browse files Browse the repository at this point in the history
use parse for BigFloat/BigInt
  • Loading branch information
JeffBezanson committed Apr 28, 2015
2 parents b47d3d0 + 70cee6f commit 00d983a
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 106 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)
2 changes: 1 addition & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ export
@__FILE__,
@int128_str,
@uint128_str,
@bigint_str,
@big_str,
@mstr, # triple-quoted strings
@cmd, # `commands`

Expand Down
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
8 changes: 6 additions & 2 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,12 @@ macro uint128_str(s)
parse(UInt128,s)
end

macro bigint_str(s)
parse(BigInt,s)
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

## system word size ##
Expand Down
20 changes: 10 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,12 @@ 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

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 @@ -1630,7 +1630,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
10 changes: 5 additions & 5 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
`(macrocall @int128_str ,s)
n))
((within-int128? s) `(macrocall @int128_str ,s))
(else `(macrocall @bigint_str ,s))))))
(else `(macrocall @big_str ,s))))))

(define (fix-uint-neg neg n)
(if neg
Expand All @@ -342,7 +342,7 @@
((<= l 32) (uint32 n))
((<= l 64) (uint64 n))
((<= l 128) `(macrocall @uint128_str ,s))
(else `(macrocall @bigint_str ,s)))))
(else `(macrocall @big_str ,s)))))

(define (sized-uint-oct-literal n s)
(if (string.find s "o0")
Expand All @@ -354,7 +354,7 @@
(else (uint64 n)))
(if (oct-within-uint128? s)
`(macrocall @uint128_str ,s)
`(macrocall @bigint_str ,s)))))
`(macrocall @big_str ,s)))))

(define (strip-leading-0s s)
(define (loop i)
Expand Down Expand Up @@ -386,7 +386,7 @@
(define (large-number? t)
(and (pair? t)
(eq? (car t) 'macrocall)
(memq (cadr t) '(@int128_str @uint128_str @bigint_str))))
(memq (cadr t) '(@int128_str @uint128_str @big_str))))

; skip to end of comment, starting at #: either #...<eol> or #= .... =#.
(define (skip-comment port)
Expand Down Expand Up @@ -797,7 +797,7 @@
(if (eq? op '-)
(if (large-number? num)
(if (eqv? (caddr num) "-170141183460469231731687303715884105728")
`(macrocall @bigint_str "170141183460469231731687303715884105728")
`(macrocall @big_str "170141183460469231731687303715884105728")
`(,(car num) ,(cadr num) ,(string.tail (caddr num) 1)))
(if (= num -9223372036854775808)
`(macrocall @int128_str "9223372036854775808")
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
Loading

0 comments on commit 00d983a

Please sign in to comment.