# Ranges with zero step

This is my first post here and English is not my native language so please excuse some (hopefully minor) mistakes.

I ran across a problem when trying to iterate over some cubic space. I want to give a function two corners of a space and a resolution for each axis. Then I want to iterate over each axis in nested loops to do something at every point in that space. My code looks something like this:

``````corner1 = [0.0, 1.0, 5.0]
corner2 = [1.0, 2.0, 5.0]
res = [100, 100, 1]
steps = abs.((corner1 .- corner2))./res
for x=corner1:steps:corner2
for y=corner1:steps:corner2
for z=corner1:steps:corner2
# do something with x, y and z
end
end
end
``````

But, if you try to run that, julia will give me an error that I cannot create a range with 0 step. Under normal circumstances this would be reasonable. Here however the length of the range is zero anyway.

I came up with a very quick and hacky fix. The fucntion `(:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64}` in twiceprecision.jl raised the error.
My function now looks like:

``````function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64}
step == 0 && start - stop != 0 && throw(ArgumentError("range step cannot be zero for non-zero length range"))
if step == 0
return 0.0:0.0
end
# rest of the function
end
``````

My problem is solved by that. But I don’t think a proper fix is that easy.

Perhaps my approach on this problem was totally wrong and I have to tackle it different.

``````for x = range(corner1, corner2, length=100)
for y = range(corner1, corner2, length=100)
for z = range(corner1, corner2, length=1)
#
end
end
end
``````

?

3 Likes

Thank you. Didn’t know about the length feature. Just gets a bit messy since I have to use an enumerate, too. But it seems like the most elegant way to do it.

1 Like

The `range()` function is really nice of you’re doing anything complicated. The colon syntax is lovely for simple things, but I find that the function itself is more clear and easier when things start to get messy.

``````help?>
search: range LinRange UnitRange StepRange StepRangeLen

range(start[, stop]; length, stop, step=1)

Given a starting value, construct a range either by
length or from start to stop, optionally with a
given step (defaults to 1, a UnitRange). One of
length or stop is required. If length, stop, and
step are all specified, they must agree.

If length and stop are provided and step is not, the
step size will be computed automatically such that
there are length linearly spaced elements in the
range (a LinRange).

If step and stop are provided and length is not, the
overall range length will be computed automatically
such that the elements are step spaced (a
StepRange).

stop may be specified as either a positional or
keyword argument.

│ Julia 1.1
│
│  stop as a positional argument requires at
│  least Julia 1.1.

Examples
≡≡≡≡≡≡≡≡≡≡

julia> range(1, length=100)
1:100

julia> range(1, stop=100)
1:100

julia> range(1, step=5, length=100)
1:5:496

julia> range(1, step=5, stop=100)
1:5:96

julia> range(1, 10, length=101)
1.0:0.09:10.0

julia> range(1, 100, step=5)
1:5:96
``````
2 Likes