From d7116374dccdb518dd2a9d764a4a25b98478ae6f Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 09:40:29 +0100 Subject: [PATCH 1/5] twiceprecision: use IEEEFloat instead of Union This is just for consistency with the rest of the code in base/twiceprecision.jl. Note that it doesn't change anything, since IEEEFloat = Union{Float16, Float32, Float64}. --- base/twiceprecision.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 8f80b2c8438a0..5a698225394e8 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -408,7 +408,7 @@ function floatrange(a::AbstractFloat, st::AbstractFloat, len::Real, divisor::Abs steprangelen_hp(T, (a,divisor), (st,divisor), nbitslen(T, len, 1), len, oneunit(len)) end -function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} +function (:)(start::T, step::T, stop::T) where T<:IEEEFloat step == 0 && throw(ArgumentError("range step cannot be zero")) # see if the inputs have exact rational approximations (and if so, # perform all computations in terms of the rationals) @@ -453,7 +453,7 @@ end step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T<:AbstractFloat} = T(r.step) step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T} = T(r.step) -function range_start_step_length(a::T, st::T, len::Integer) where T<:Union{Float16,Float32,Float64} +function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat len = len + 0 # promote with Int start_n, start_d = rat(a) step_n, step_d = rat(st) From 1c5dd9179e7e1313d56d99f29bba86f5492fd7f7 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 09:43:11 +0100 Subject: [PATCH 2/5] Add range_start_step_length definition --- base/twiceprecision.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 5a698225394e8..850f5007b6cbb 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -453,6 +453,9 @@ end step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T<:AbstractFloat} = T(r.step) step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T} = T(r.step) +range_start_step_length(a, st::IEEEFloat, len::Integer) = + range_start_step_length(oftype(st, a), st, len) + function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat len = len + 0 # promote with Int start_n, start_d = rat(a) From 0e1f7a87014e5d7f5c8d3145add5ba3c15e78099 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 09:54:14 +0100 Subject: [PATCH 3/5] Add test --- test/ranges.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/ranges.jl b/test/ranges.jl index a7f26c7efa629..f4313c10127bd 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1612,6 +1612,11 @@ end @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} end +@testset "Issue #44292" begin + x = @inferred range(0, step=0.2, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} +end + @testset "Views of ranges" begin @test view(Base.OneTo(10), Base.OneTo(5)) === Base.OneTo(5) @test view(1:10, 1:5) === 1:5 From 8cf3581a6fc66324bfefd53510785093adf3dec6 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 17:14:05 +0100 Subject: [PATCH 4/5] Fix `range(; step, stop, length)` --- base/twiceprecision.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 850f5007b6cbb..6d91431e47abb 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -474,6 +474,11 @@ function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat steprangelen_hp(T, a, st, 0, len, 1) end +function range_step_stop_length(step::IEEEFloat, stop, len::Integer) + r = range_start_step_length(stop, negate(step), len) + reverse(r) +end + # This assumes that r.step has already been split so that (0:len-1)*r.step.hi is exact function unsafe_getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, i::Integer) where T # Very similar to _getindex_hiprec, but optimized to avoid a 2nd call to add12 From dd6c2c64608cc9f7b43c6a393c4c0c874ebcd12f Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 17:16:54 +0100 Subject: [PATCH 5/5] Add more tests --- test/ranges.jl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/ranges.jl b/test/ranges.jl index f4313c10127bd..536c1f4710d9d 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1613,8 +1613,15 @@ end end @testset "Issue #44292" begin - x = @inferred range(0, step=0.2, length=5) - @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + let x = @inferred range(0, step=0.2, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x == [0.0, 0.2, 0.4, 0.6, 0.8] + end + + let x = @inferred range(stop=1, step=0.2, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x == [0.2, 0.4, 0.6, 0.8, 1.0] + end end @testset "Views of ranges" begin