Skip to content

Commit ebc5eff

Browse files
committed
Fix length for StepRange
1 parent 7f2cb6c commit ebc5eff

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/FixedPointNumbers.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
88
div, fld, rem, mod, mod1, fld1, min, max, minmax,
99
rand
1010

11-
using Base.Checked: checked_add, checked_sub
11+
using Base.Checked: checked_add, checked_sub, checked_div
1212

1313
using Base: @pure
1414

@@ -142,6 +142,21 @@ for f in (:+, :-, :rem, :mod, :mod1, :min, :max)
142142
end
143143
end
144144

145+
function Base.unsafe_length(r::StepRange{X,Y}) where {X<:FixedPoint{<:ShorterThanInt}, Y<:FixedPoint{<:ShorterThanInt}}
146+
start, step, stop = reinterpret(r.start), reinterpret(r.step), reinterpret(r.stop)
147+
return div(Int(stop) - Int(start) + Int(step), Int(step))
148+
end
149+
function Base.unsafe_length(r::StepRange{X,Y}) where {X<:FixedPoint, Y<:FixedPoint}
150+
start, step, stop = reinterpret(r.start), reinterpret(r.step), reinterpret(r.stop)
151+
return div((stop - start) + step, step)
152+
end
153+
Base.length(r::StepRange{X,Y}) where {X<:FixedPoint{<:ShorterThanInt}, Y<:FixedPoint{<:ShorterThanInt}} =
154+
Base.unsafe_length(r)
155+
function Base.length(r::StepRange{X,Y}) where {X<:FixedPoint, Y<:FixedPoint}
156+
start, step, stop = reinterpret(r.start), reinterpret(r.step), reinterpret(r.stop)
157+
return checked_div(checked_add(checked_sub(stop, start), step), step)
158+
end
159+
145160
# Printing. These are used to generate type-symbols, so we need them
146161
# before we include any files.
147162
function showtype(io::IO, ::Type{X}) where {X <: FixedPoint}

test/fixed.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,20 @@ end
122122
@test length(typemin(QInt1):typemax(QInt1)) == typemax(Int)
123123
end
124124

125+
@testset "step range" begin
126+
r = typemin(Q0f7):eps(Q0f7):typemax(Q0f7)
127+
counter = 0
128+
for x in r
129+
counter += 1
130+
end
131+
@test counter == 256
132+
@test length(r) == 256
133+
QInt1 = Fixed{Int,1}
134+
@test length(QInt1(0):eps(QInt1):typemax(QInt1)-eps(QInt1)) == typemax(Int)
135+
@test Base.unsafe_length(typemin(QInt1):eps(QInt1):typemax(QInt1)-eps(QInt1)) == -1
136+
@test_throws OverflowError length(QInt1(-1):eps(QInt1):typemax(QInt1)-eps(QInt1))
137+
end
138+
125139
@testset "reductions" begin
126140
F8 = Fixed{Int8,8}
127141
a = F8[0.498, 0.1]

test/normed.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,11 @@ end
318318
end
319319
@test counter == 256
320320
@test length(N0f8(0):eps(N0f8):N0f8(1)) == 256
321-
r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48))
321+
r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, UInt8(48))
322322
@test length(r) == 48
323+
NInt1 = Normed{UInt,1}
324+
@test length(NInt1(0):NInt1(1):typemax(NInt1)-oneunit(NInt1)) == typemax(UInt)
325+
@test_throws OverflowError length(NInt1(0):NInt1(1):typemax(NInt1))
323326
end
324327

325328
@testset "Promotion within Normed" begin

0 commit comments

Comments
 (0)