From 7bc0567b68ab31caffe813f18aa9cf587cd02afe Mon Sep 17 00:00:00 2001 From: quinnj Date: Wed, 6 Mar 2019 23:07:55 -0700 Subject: [PATCH 1/4] Fix #5 by using as many BigInt in-place ops as possible to avoid allocations. --- benchmarks/floats.jl | 5 ++-- src/floats.jl | 55 +++++++++++++++++++++++++++++++------------- test/floats.jl | 3 +-- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/benchmarks/floats.jl b/benchmarks/floats.jl index c26350e..0209e14 100644 --- a/benchmarks/floats.jl +++ b/benchmarks/floats.jl @@ -51,9 +51,10 @@ end function prof(n) - io = IOBuffer("3.2925339999999996e-18") + io = IOBuffer("2.2250738585072011e-308") + res = Parsers.Result(Float64) for i = 1:n seekstart(io) - Main.Parsers.xparse(io, Float64) + r = Parsers.defaultparser(io, res) end end \ No newline at end of file diff --git a/src/floats.jl b/src/floats.jl index 01ab921..c1be517 100644 --- a/src/floats.jl +++ b/src/floats.jl @@ -1,12 +1,20 @@ +using Base.GMP, Base.GMP.MPZ + +const ONE = BigInt(1) +const NUM = BigInt() +const QUO = BigInt() +const REM = BigInt() +const ODD = big(22250738585072011) + const BIG_E = UInt8('E') const LITTLE_E = UInt8('e') const bipows5 = [big(5)^x for x = 0:325] function roundQuotient(num, den) - quo, rem = divrem(num, den) - q = Int64(quo) - cmpflg = cmp(rem << 1, den) + MPZ.tdiv_qr!(QUO, REM, num, den) + q = Int64(QUO) + cmpflg = cmp(MPZ.mul_2exp!(REM, 1), den) return ((q & 1) == 0 ? 1 == cmpflg : -1 < cmpflg) ? q + 1 : q end @@ -30,9 +38,30 @@ significantbits(::Type{Float16}) = 11 significantbits(::Type{Float32}) = 24 significantbits(::Type{Float64}) = 53 -bitlength(this) = Base.GMP.MPZ.sizeinbase(this, 2) +bitlength(this) = GMP.MPZ.sizeinbase(this, 2) bits(::Type{T}) where {T <: Union{Float16, Float32, Float64}} = 8sizeof(T) +BigInt!(y::BigInt, x::BigInt) = x +# copied from gmp.jl:285 +function BigInt!(y::BigInt, x::Integer) + x == 0 && return y + nd = ndigits(x, base=2) + z = GMP.MPZ.realloc2!(y, nd) + s = sign(x) + s == -1 && (x = -x) + x = unsigned(x) + size = 0 + limbnbits = sizeof(GMP.Limb) << 3 + while nd > 0 + size += 1 + unsafe_store!(z.d, x % GMP.Limb, size) + x >>>= limbnbits + nd -= limbnbits + end + z.size = s*size + z +end + @inline function scale(::Type{T}, v, exp) where {T <: Union{Float16, Float32, Float64}} ms = maxsig(T) cl = ceillog5(T) @@ -45,29 +74,23 @@ bits(::Type{T}) where {T <: Union{Float16, Float32, Float64}} = 8sizeof(T) end end v == 0 && return zero(T) - # if v < 2ms - # if 0 <= exp < 2cl - # return T(Base.twiceprecision(Base.TwicePrecision{T}(v) * pow10(T, exp), significantbits(T))) - # elseif -2cl < exp < 0 - # return T(Base.twiceprecision(Base.TwicePrecision{T}(v) / pow10(T, -exp), significantbits(T))) - # end - # end - mant = big(v) + mant = BigInt!(NUM, v) if 0 <= exp < 327 - num = mant * bipows5[exp+1] + num = MPZ.mul!(mant, bipows5[exp+1]) bex = bitlength(num) - significantbits(T) bex <= 0 && return ldexp(T(num), exp) - quo = roundQuotient(num, big(1) << bex) + MPZ.mul_2exp!(MPZ.set_si!(ONE, 1), bex) + quo = roundQuotient(num, ONE) return ldexp(T(quo), bex + exp) elseif -327 < exp < 0 maxpow = length(bipows5) - 1 scl = (-exp <= maxpow) ? bipows5[-exp+1] : bipows5[maxpow+1] * bipows5[-exp-maxpow+1] bex = bitlength(mant) - bitlength(scl) - significantbits(T) - num = mant << -bex + num = MPZ.mul_2exp!(mant, -bex) quo = roundQuotient(num, scl) # @info "debug" mant=mant exp=exp num=num quo=quo lh=(bits(T) - leading_zeros(quo)) rh=significantbits(T) bex=bex - if (bits(T) - leading_zeros(quo) > significantbits(T)) || mant == big(22250738585072011) + if (bits(T) - leading_zeros(quo) > significantbits(T)) || exp == -324 bex += 1 quo = roundQuotient(num, scl << 1) end diff --git a/test/floats.jl b/test/floats.jl index c52ee1f..38aa5b5 100644 --- a/test/floats.jl +++ b/test/floats.jl @@ -292,7 +292,6 @@ r = Parsers.defaultparser(IOBuffer("1e+18446744073709551616"), Parsers.Result(Fl @test r.result === +Inf @test r.code === OK | EOF - # Parse errors r = Parsers.defaultparser(IOBuffer("1e"), Parsers.Result(Float64)) @test r.result === missing @@ -311,7 +310,7 @@ r = Parsers.defaultparser(IOBuffer("1\x00.2"), Parsers.Result(Float64)) r = Parsers.defaultparser(IOBuffer("2.2250738585072012e-308"), Parsers.Result(Float64)) @test r.result === 2.2250738585072014e-308 @test r.code === OK | EOF -# http:#www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ +# http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ r = Parsers.defaultparser(IOBuffer("2.2250738585072011e-308"), Parsers.Result(Float64)) @test r.result === 2.225073858507201e-308 @test r.code === OK | EOF From 66eb9dce08a0031af2385ff02d6224932436020d Mon Sep 17 00:00:00 2001 From: quinnj Date: Thu, 7 Mar 2019 11:35:17 -0700 Subject: [PATCH 2/4] Avoid a few more allocations --- benchmarks/floats.jl | 4 ++-- benchmarks/parsers.jl | 7 +++++++ src/floats.jl | 14 ++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/benchmarks/floats.jl b/benchmarks/floats.jl index 0209e14..ea917f6 100644 --- a/benchmarks/floats.jl +++ b/benchmarks/floats.jl @@ -50,8 +50,8 @@ function bench(n=100_000) end -function prof(n) - io = IOBuffer("2.2250738585072011e-308") +function prof(str, n) + io = IOBuffer(str) res = Parsers.Result(Float64) for i = 1:n seekstart(io) diff --git a/benchmarks/parsers.jl b/benchmarks/parsers.jl index 58cc584..d8f3e3b 100644 --- a/benchmarks/parsers.jl +++ b/benchmarks/parsers.jl @@ -32,6 +32,13 @@ run(@benchmarkable Parsers.parse!($l, io, r) setup=(io = IOBuffer("0"); r = Pars l = Parsers.Delimited(Parsers.Quoted(Parsers.Strip(Parsers.Sentinel(["NA"])))) run(@benchmarkable Parsers.parse!($l, io, r) setup=(io = IOBuffer("0"); r = Parsers.Result($T))) +run(@benchmarkable Parsers.defaultparser(io, r) setup=(io = IOBuffer("99999999999999974834176"); r = Parsers.Result($T))) +run(@benchmarkable Parsers.defaultparser(io, r) setup=(io = IOBuffer("1.7976931348623157e308"); r = Parsers.Result($T))) + +run(@benchmarkable Parsers.defaultparser(io, r) setup=(io = IOBuffer("2.2250738585072011e-308"); r = Parsers.Result($T))) +run(@benchmarkable Parsers.defaultparser(io, r) setup=(io = IOBuffer("0.0017138347201173243"); r = Parsers.Result($T))) + + # Tuple{Ptr{UInt8}, Int} T = Tuple{Ptr{UInt8}, Int} run(@benchmarkable Parsers.defaultparser(io, r) setup=(io = IOBuffer("0"); r = Parsers.Result($T))) diff --git a/src/floats.jl b/src/floats.jl index c1be517..9133b6a 100644 --- a/src/floats.jl +++ b/src/floats.jl @@ -4,7 +4,7 @@ const ONE = BigInt(1) const NUM = BigInt() const QUO = BigInt() const REM = BigInt() -const ODD = big(22250738585072011) +const SCL = BigInt() const BIG_E = UInt8('E') const LITTLE_E = UInt8('e') @@ -42,6 +42,7 @@ bitlength(this) = GMP.MPZ.sizeinbase(this, 2) bits(::Type{T}) where {T <: Union{Float16, Float32, Float64}} = 8sizeof(T) BigInt!(y::BigInt, x::BigInt) = x +BigInt!(y::BigInt, x::Union{Clong,Int32}) = MPZ.set_si!(y, x) # copied from gmp.jl:285 function BigInt!(y::BigInt, x::Integer) x == 0 && return y @@ -84,15 +85,20 @@ end return ldexp(T(quo), bex + exp) elseif -327 < exp < 0 maxpow = length(bipows5) - 1 - scl = (-exp <= maxpow) ? bipows5[-exp+1] : - bipows5[maxpow+1] * bipows5[-exp-maxpow+1] + scl = SCL + if -exp <= maxpow + MPZ.set!(scl, bipows5[-exp+1]) + else + MPZ.set!(scl, bipows5[maxpow+1]) + MPZ.mul!(scl, bipows5[-exp-maxpow+1]) + end bex = bitlength(mant) - bitlength(scl) - significantbits(T) num = MPZ.mul_2exp!(mant, -bex) quo = roundQuotient(num, scl) # @info "debug" mant=mant exp=exp num=num quo=quo lh=(bits(T) - leading_zeros(quo)) rh=significantbits(T) bex=bex if (bits(T) - leading_zeros(quo) > significantbits(T)) || exp == -324 bex += 1 - quo = roundQuotient(num, scl << 1) + quo = roundQuotient(num, MPZ.mul_2exp!(scl, 1)) end if exp <= -324 return T(ldexp(BigFloat(quo), bex + exp)) From 95cd4f145cbc42d3368ed2881aa34d90a857e4be Mon Sep 17 00:00:00 2001 From: quinnj Date: Fri, 8 Mar 2019 11:22:19 -0700 Subject: [PATCH 3/4] More perf improvements and make new pre-allocated BigInts for float parsing thread-safe --- src/Parsers.jl | 57 +++++++++++++++++++++++++++++++++++++++++++------- src/floats.jl | 24 ++++++++++----------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/Parsers.jl b/src/Parsers.jl index 3a77cba..167338e 100644 --- a/src/Parsers.jl +++ b/src/Parsers.jl @@ -9,9 +9,35 @@ function __init__() for results in RESULTS Threads.resize_nthreads!(results) end + Threads.resize_nthreads!(STRINGBUFFERS) + Threads.resize_nthreads!(ONES) + Threads.resize_nthreads!(NUMS) + Threads.resize_nthreads!(QUOS) + Threads.resize_nthreads!(REMS) + Threads.resize_nthreads!(SCLS) return end +mutable struct StringBuffer <: IO + data::String + ptr::Int64 + size::Int64 + StringBuffer() = new("", 1, 0) +end + +Base.eof(io::StringBuffer) = (io.ptr - 1) == io.size +Base.position(io::StringBuffer) = io.ptr - 1 + +const STRINGBUFFERS = [StringBuffer()] + +function getio(str) + io = STRINGBUFFERS[Threads.threadid()] + io.data = str + io.ptr = 1 + io.size = sizeof(str) + return io +end + """ Parsers.readbyte(io::IO)::UInt8 @@ -30,8 +56,9 @@ readbyte(from::IO) = Base.read(from, UInt8) peekbyte(from::IO) = UInt8(Base.peek(from)) function readbyte(from::IOBuffer) - @inbounds byte = from.data[from.ptr] - from.ptr = from.ptr + 1 + i = from.ptr + @inbounds byte = from.data[i] + from.ptr = i + 1 return byte end @@ -40,6 +67,18 @@ function peekbyte(from::IOBuffer) return byte end +function readbyte(from::StringBuffer) + i = from.ptr + s = from.data + from.ptr = i + 1 + GC.@preserve s unsafe_load(pointer(s, i)) +end + +function peekbyte(from::StringBuffer) + s = from.data + GC.@preserve s unsafe_load(pointer(s, from.ptr)) +end + """ Parsers.fastseek!(io::IO, n::Integer) @@ -48,8 +87,8 @@ end function fastseek! end fastseek!(io::IO, n::Integer) = seek(io, n) -function fastseek!(io::IOBuffer, n::Integer) - io.ptr = n+1 +function fastseek!(io::Union{IOBuffer, StringBuffer}, n::Integer) + io.ptr = n + 1 return end @@ -312,7 +351,7 @@ function parse end function tryparse end function parse(str::AbstractString, ::Type{T}; kwargs...) where {T} - io = IOBuffer(str) + io = getio(str) res = parse(defaultparser, io, T; kwargs...) return ok(res.code) ? res.result : throw(Error(io, res)) end @@ -321,7 +360,7 @@ function parse(io::IO, ::Type{T}; kwargs...) where {T} return ok(res.code) ? res.result : throw(Error(io, res)) end function parse(f::Base.Callable, str::AbstractString, ::Type{T}; kwargs...) where {T} - io = IOBuffer(str) + io = getio(str) res = parse!(f, io, Result(T); kwargs...) return ok(res.code) ? res.result : throw(Error(io, res)) end @@ -331,7 +370,8 @@ function parse(f::Base.Callable, io::IO, ::Type{T}; kwargs...) where {T} end function tryparse(str::AbstractString, ::Type{T}; kwargs...) where {T} - res = parse(defaultparser, IOBuffer(str), T; kwargs...) + io = getio(str) + res = parse(defaultparser, io, T; kwargs...) return ok(res.code) ? res.result : nothing end function tryparse(io::IO, ::Type{T}; kwargs...) where {T} @@ -339,7 +379,8 @@ function tryparse(io::IO, ::Type{T}; kwargs...) where {T} return ok(res.code) ? res.result : nothing end function tryparse(f::Base.Callable, str::AbstractString, ::Type{T}; kwargs...) where {T} - res = parse!(f, IOBuffer(str), Result(T); kwargs...) + io = getio(str) + res = parse!(f, io, Result(T); kwargs...) return ok(res.code) ? res.result : nothing end function tryparse(f::Base.Callable, io::IO, ::Type{T}; kwargs...) where {T} diff --git a/src/floats.jl b/src/floats.jl index 9133b6a..b52e15a 100644 --- a/src/floats.jl +++ b/src/floats.jl @@ -1,10 +1,10 @@ using Base.GMP, Base.GMP.MPZ -const ONE = BigInt(1) -const NUM = BigInt() -const QUO = BigInt() -const REM = BigInt() -const SCL = BigInt() +const ONES = [BigInt(1)] +const NUMS = [BigInt()] +const QUOS = [BigInt()] +const REMS = [BigInt()] +const SCLS = [BigInt()] const BIG_E = UInt8('E') const LITTLE_E = UInt8('e') @@ -12,9 +12,9 @@ const LITTLE_E = UInt8('e') const bipows5 = [big(5)^x for x = 0:325] function roundQuotient(num, den) - MPZ.tdiv_qr!(QUO, REM, num, den) - q = Int64(QUO) - cmpflg = cmp(MPZ.mul_2exp!(REM, 1), den) + @inbounds quo, rem = MPZ.tdiv_qr!(QUOS[Threads.threadid()], REMS[Threads.threadid()], num, den) + q = Int64(quo) + cmpflg = cmp(MPZ.mul_2exp!(rem, 1), den) return ((q & 1) == 0 ? 1 == cmpflg : -1 < cmpflg) ? q + 1 : q end @@ -75,17 +75,17 @@ end end end v == 0 && return zero(T) - mant = BigInt!(NUM, v) + @inbounds mant = BigInt!(NUMS[Threads.threadid()], v) if 0 <= exp < 327 num = MPZ.mul!(mant, bipows5[exp+1]) bex = bitlength(num) - significantbits(T) bex <= 0 && return ldexp(T(num), exp) - MPZ.mul_2exp!(MPZ.set_si!(ONE, 1), bex) - quo = roundQuotient(num, ONE) + @inbounds one = MPZ.mul_2exp!(MPZ.set_si!(ONES[Threads.threadid()], 1), bex) + quo = roundQuotient(num, one) return ldexp(T(quo), bex + exp) elseif -327 < exp < 0 maxpow = length(bipows5) - 1 - scl = SCL + @inbounds scl = SCLS[Threads.threadid()] if -exp <= maxpow MPZ.set!(scl, bipows5[-exp+1]) else From bb0931ea1a83d14fe4bc3ddbf2e064a8a5925ecc Mon Sep 17 00:00:00 2001 From: quinnj Date: Fri, 8 Mar 2019 15:45:54 -0700 Subject: [PATCH 4/4] Add a bunch of tests: --- test/floats.jl | 359 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 357 insertions(+), 2 deletions(-) diff --git a/test/floats.jl b/test/floats.jl index 38aa5b5..945a180 100644 --- a/test/floats.jl +++ b/test/floats.jl @@ -338,8 +338,6 @@ r = Parsers.defaultparser(IOBuffer("1.000000000000000111022302462515654042363166 r = Parsers.defaultparser(IOBuffer("1.00000000000000011102230246251565404236316680908203126"), Parsers.Result(Float64)) @test r.result === 1.0000000000000002 @test r.code === OK | EOF -# # Slightly higher, but you have to read all the way to the end. -# r = Parsers.defaultparser(IOBuffer("1.00000000000000011102230246251565404236316680908203125"), Parsers.Result(Float64)) r = Parsers.defaultparser(IOBuffer("-5.871153289887625082e-01"), Parsers.Result(Float64)) @test r.result === -5.871153289887625082e-01 @@ -375,4 +373,361 @@ r = Parsers.defaultparser(IOBuffer(".24409E+03 "), Parsers.Result(Float64)) @test r.result === 244.09 @test r.code === OK | EOF +# from https://www.icir.org/vern/papers/testbase-report.pdf +float = 5.0 * exp10(+125) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 69.0 * exp10(+267) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 999.0 * exp10(-26) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7861.0 * exp10(-34) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 75569.0 * exp10(-254) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 928609.0 * exp10(-261) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 9210917.0 * exp10(+80) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 84863171.0 * exp10(+114) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 653777767.0 * exp10(+273) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5232604057.0 * exp10(-298) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 27235667517.0 * exp10(-109) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 653532977297.0 * exp10(-123) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 3142213164987.0 * exp10(-294) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 46202199371337.0 * exp10(-72) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 231010996856685.0 * exp10(-73) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 9324754620109615.0 * exp10(+212) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 78459735791271921.0 * exp10(+49) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 272104041512242479.0 * exp10(+200) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6802601037806061975.0 * exp10(+198) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 20505426358836677347.0 * exp10(-221) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 836168422905420598437.0 * exp10(-234) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 4891559871276714924261.0 * exp10(+222) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF + +float = 9.0 * exp10(-265) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 85.0 * exp10(-037) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 623.0 * exp10(+100) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 3571.0 * exp10(+263) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 81661.0 * exp10(+153) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 920657.0 * exp10(-023) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 4603285.0 * exp10(-024) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 87575437.0 * exp10(-309) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 245540327.0 * exp10(+122) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6138508175.0 * exp10(+120) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 83356057653.0 * exp10(+193) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 619534293513.0 * exp10(+124) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 2335141086879.0 * exp10(+218) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 36167929443327.0 * exp10(-159) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 609610927149051.0 * exp10(-255) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 3743626360493413.0 * exp10(-165) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 94080055902682397.0 * exp10(-242) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 899810892172646163.0 * exp10(+283) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7120190517612959703.0 * exp10(+120) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 25188282901709339043.0 * exp10(-252) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 308984926168550152811.0 * exp10(-052) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6372891218502368041059.0 * exp10(+064) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF + +float = 8511030020275656.0 * exp2(-0342) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5201988407066741.0 * exp2(-0824) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6406892948269899.0 * exp2(+0237) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8431154198732492.0 * exp2(+0072) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6475049196144587.0 * exp2(+0099) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8274307542972842.0 * exp2(+0726) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5381065484265332.0 * exp2(-0456) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6761728585499734.0 * exp2(-1057) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7976538478610756.0 * exp2(+0376) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5982403858958067.0 * exp2(+0377) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5536995190630837.0 * exp2(+0093) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7225450889282194.0 * exp2(+0710) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7225450889282194.0 * exp2(+0709) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8703372741147379.0 * exp2(+0117) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8944262675275217.0 * exp2(-1001) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7459803696087692.0 * exp2(-0707) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6080469016670379.0 * exp2(-0381) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8385515147034757.0 * exp2(+0721) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7514216811389786.0 * exp2(-0828) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8397297803260511.0 * exp2(-0345) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6733459239310543.0 * exp2(+0202) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8091450587292794.0 * exp2(-0473) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF + +float = 6567258882077402.0 * exp2(+952) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6712731423444934.0 * exp2(+535) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6712731423444934.0 * exp2(+534) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5298405411573037.0 * exp2(-957) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5137311167659507.0 * exp2(-144) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6722280709661868.0 * exp2(+363) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5344436398034927.0 * exp2(-169) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8369123604277281.0 * exp2(-853) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8995822108487663.0 * exp2(-780) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8942832835564782.0 * exp2(-383) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8942832835564782.0 * exp2(-384) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8942832835564782.0 * exp2(-385) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6965949469487146.0 * exp2(-249) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6965949469487146.0 * exp2(-250) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6965949469487146.0 * exp2(-251) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7487252720986826.0 * exp2(+548) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 5592117679628511.0 * exp2(+164) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8887055249355788.0 * exp2(+665) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 6994187472632449.0 * exp2(+690) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8797576579012143.0 * exp2(+588) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 7363326733505337.0 * exp2(+272) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF +float = 8549497411294502.0 * exp2(-448) +r = Parsers.defaultparser(IOBuffer(string(float)), Parsers.Result(Float64)) +@test r.result === float +@test r.code === OK | EOF + end # @testset