Reverse UnitRange

I’m trying to implement SystemVerilog style bit indexing/slicing operator:

a = 0b11100
b[4:2] == 0b111

But I realize that the colon operator doesn’t work when the second index is lower than the first index:

julia> dump(4:2)
UnitRange{Int64}
  start: Int64 4
  stop: Int64 3

The stop index doesn’t go to 2 as expected. Most solutions for reverse range uses something like 4:-1:2 which is not as convenient as 4:2. Is there a way to make 4:2 work?

My basic understanding is that 4:2 actually works and is purposefully an “empty” range. It’s just that a:b is synctactic sugar for a:1:b. You could define your own operator like (edited the snippet)

julia> …(a,b) = (a<b) ? (a:b) : (a:-1:b)
… (generic function with 1 method)

julia> 2…4
2:4

julia> 4…2
4:-1:2

I guess. And there is probably a better symbol for that…

4 Likes

Looks like @briochemc has it right. Why do I get the 4:3 when I type 4:2 at the prompt?

julia> 4:2
4:3

julia> collect(4:2)
Int64[]

julia> 4:-1:2
4:-1:2

julia> z=collect(4:-1:2)
3-element Vector{Int64}:
 4
 3
 2
1 Like

I guess n:n-1 is the “canonical” form for all empty ranges. All empty ranges are converted to this form on construction.

Among other things, it makes sense that a 0-length range starting at n ends at n-1. Length of a:b is consistently defined as length(a:b) = b-a+1

Also we have 4:2 == 4:0

2 Likes