-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subtracting a range from another range with the same step #10391
Comments
For two |
We can have all the |
We could. Depends whether there are enough cases where people subtract ranges with different steps that the efficiency of returning a range from |
This isn't necessarily limited to subtraction, e.g.: julia> (5:-1:1) + (1:5)
ERROR: ArgumentError: step cannot be zero
in steprange_last at ./range.jl:47
in + at operators.jl:331 but that's probably less common in practice. |
Or multiplication: julia> (1:5)*0
ERROR: ArgumentError: step cannot be zero
in steprange_last at ./range.jl:47
in .* at range.jl:465
in * at abstractarray.jl:466 |
FloatRanges don't have this restriction and actually behave as you'd want: julia> (2.:6.) - (1.:5.)
1.0:0.0:1.0
julia> collect(ans)
5-element Array{Float64,1}:
1.0
1.0
1.0
1.0
1.0
julia> (1:5) * 0.0
0.0:0.0:0.0
julia> collect(ans)
5-element Array{Float64,1}:
0.0
0.0
0.0
0.0
0.0 |
Instead of returning Arrays you can just promote from a Given the following issue
Is there a reason we can't implement something like import Base.-
function -( x :: UnitRange
, y :: UnitRange
)
length(x) != length(y) && throw(DimensionMismatch)
return StepRangeLen(x.start-y.start, 0, length(x))
end
function -( x :: StepRange
, y :: StepRange
)
length(x) != length(y) && throw(DimensionMismatch)
if x.step == y.step
return StepRangeLen(x.start-y.start, 0, length(x))
else
return (x.start-y.start):(x.step-y.step):(x.stop-y.stop)
end
end Also this seems related to
which could also be promoted to a |
Thanks for bringing that here. Yes, I do think we could use Unfortunately, implementing support for other permutations that can sometimes return a thing with step size zero is a bigger challenge (e.g., things like The alternative path forward would be to simply wholesale replace |
I've just come up against this problem too, when trying to (fairly naturally) call Changing I believe this is achieved by replacing in # Range from start to stop: range(a, [step=s,] stop=b), no length
_range(start, step, stop, ::Nothing) = (:)(start, step, stop)
_range(start, ::Nothing, stop, ::Nothing) = (:)(start, stop)
# Range of a given length: range(a, [step=s,] length=l), no stop
_range(a::Real, ::Nothing, ::Nothing, len::Integer) = UnitRange{typeof(a)}(a, oftype(a, a+len-1))
_range(a::AbstractFloat, ::Nothing, ::Nothing, len::Integer) = _range(a, oftype(a, 1), nothing, len)
_range(a::AbstractFloat, st::AbstractFloat, ::Nothing, len::Integer) = _range(promote(a, st)..., nothing, len)
_range(a::Real, st::AbstractFloat, ::Nothing, len::Integer) = _range(float(a), st, nothing, len)
_range(a::AbstractFloat, st::Real, ::Nothing, len::Integer) = _range(a, float(st), nothing, len)
_range(a, ::Nothing, ::Nothing, len::Integer) = _range(a, oftype(a-a, 1), nothing, len)
_range(a::T, step, ::Nothing, len::Integer) where {T} =
_rangestyle(OrderStyle(T), ArithmeticStyle(T), a, step, len)
_rangestyle(::Ordered, ::ArithmeticWraps, a::T, step::S, len::Integer) where {T,S} =
StepRange{T,S}(a, step, convert(T, a+step*(len-1)))
_rangestyle(::Any, ::Any, a::T, step::S, len::Integer) where {T,S} =
StepRangeLen{typeof(a+0*step),T,S}(a, step, len) with just _range(start, step, stop, ::Nothing) = (:)(start, step, stop)
_range(start, ::Nothing, stop, ::Nothing) = (:)(start, stop)
_range(start, step, ::Nothing, len) = StepRangeLen(start, step, len)
_range(start, ::Nothing, ::Nothing, len) = UnitRange(start, oftype(start,start+len-1)) |
Ah - it was deep in the past. I will just add a problem I reported in #35370 that is not duplicate of what already is reported here as also is a bug (so when redesigning Base it should be taken also into consideration):
|
I'm not sure if there's anything we can do about this, but this throws an error:
This can break code that expects that any two
AbstractVector{T<:Number}
s of the same length can be subtracted from each other.The text was updated successfully, but these errors were encountered: