From 97f6e6ce13bc48c9b7a374bbc07e83133b186c18 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Sep 2021 11:02:18 -0400 Subject: [PATCH] ranges: broadcast preserves length Fixes #42291 --- base/broadcast.jl | 17 ++++++++++------- test/ranges.jl | 13 +++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index af9a809e7c59b..d5daab992390c 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -1087,10 +1087,12 @@ broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::LinRange) = LinRange(-r.star # For #18336 we need to prevent promotion of the step type: broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractRange, x::Number) = range(first(r) + x, step=step(r), length=length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::AbstractRange) = range(x + first(r), step=step(r), length=length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::OrdinalRange, x::Real) = range(first(r) + x, last(r) + x, step=step(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::Real) = range(x + first(r), x + last(r), step=step(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Real) = range(first(r) + x, last(r) + x) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::AbstractUnitRange) = range(x + first(r), x + last(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::OrdinalRange, x::Integer) = range(first(r) + x, last(r) + x, step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::OrdinalRange) = range(x + first(r), x + last(r), step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Integer) = range(first(r) + x, last(r) + x) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::AbstractUnitRange) = range(x + first(r), x + last(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Real) = range(first(r) + x, length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::AbstractUnitRange) = range(x + first(r), length=length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::StepRangeLen{T}, x::Number) where T = StepRangeLen{typeof(T(r.ref)+x)}(r.ref + x, r.step, length(r), r.offset) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::StepRangeLen{T}) where T = @@ -1101,9 +1103,10 @@ broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r1::AbstractRange, r2::Abstract broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange, x::Number) = range(first(r) - x, step=step(r), length=length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::AbstractRange) = range(x - first(r), step=-step(r), length=length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange, x::Real) = range(first(r) - x, last(r) - x, step=step(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Real, r::OrdinalRange) = range(x - first(r), x - last(r), step=-step(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Real) = range(first(r) - x, last(r) - x) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange, x::Integer) = range(first(r) - x, last(r) - x, step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Integer, r::OrdinalRange) = range(x - first(r), x - last(r), step=-step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Integer) = range(first(r) - x, last(r) - x) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Real) = range(first(r) - x, length=length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::StepRangeLen{T}, x::Number) where T = StepRangeLen{typeof(T(r.ref)-x)}(r.ref - x, r.step, length(r), r.offset) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::StepRangeLen{T}) where T = diff --git a/test/ranges.jl b/test/ranges.jl index e46207cc1481c..121e5a97cb517 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -687,14 +687,14 @@ end end @testset "broadcasted operations with scalars" for T in (Int, UInt, Int128) @test broadcast(-, T(1):3, 2) === T(1)-2:1 - @test broadcast(-, T(1):3, 0.25) === T(1)-0.25:3-0.25 + @test broadcast(-, T(1):3, 0.25) === range(T(1)-0.25, length=T(3)) == T(1)-0.25:3-0.25 @test broadcast(+, T(1):3) === T(1):3 @test broadcast(+, T(1):3, 2) === T(3):5 - @test broadcast(+, T(1):3, 0.25) === T(1)+0.25:3+0.25 + @test broadcast(+, T(1):3, 0.25) === range(T(1)+0.25, length=T(3)) == T(1)+0.25:3+0.25 @test broadcast(+, T(1):2:6, 1) === T(2):2:6 - @test broadcast(+, T(1):2:6, 0.3) === T(1)+0.3:2:5+0.3 + @test broadcast(+, T(1):2:6, 0.3) === range(T(1)+0.3, step=2, length=T(3)) == T(1)+0.3:2:5+0.3 @test broadcast(-, T(1):2:6, 1) === T(0):2:4 - @test broadcast(-, T(1):2:6, 0.3) === T(1)-0.3:2:5-0.3 + @test broadcast(-, T(1):2:6, 0.3) === range(T(1)-0.3, step=2, length=T(3)) == T(1)-0.3:2:5-0.3 is_unsigned = T <: Unsigned is_unsigned && @test length(broadcast(-, T(1):3, 2)) === length(T(1)-2:T(3)-2) @test broadcast(-, T(1):3) == -T(1):-T(1):-T(3) @@ -1534,6 +1534,11 @@ end @test @inferred(x .\ r) === 0.5:0.5:2.5 @test @inferred(2 .* (r .+ 1) .+ 2) == 6:2:14 + + # issue #42291 + @test length((1:5) .- 1/7) == 5 + @test length((1:5) .+ -1/7) == 5 + @test length(-1/7 .+ (1:5)) == 5 end @testset "Bad range calls" begin