Skip to content

Commit

Permalink
linspace: fix 32-bit failures
Browse files Browse the repository at this point in the history
The issue was that doing `one(p) << p` where p is Int produces zero
on a 32-bit system if p is larger than 32, which it can be for some
Float64 arguments.

Getting tests to pass for 32-bit also required avoiding taking the
length of LinSpace objects whose lengths are 2^31 or longer. This is
a bit of a more general problem since we can represent FloatRange
and LinSpace objects whose length cannot be represented as an Int on
both 64- and 32-bit platforms, although it is, of course, easier to
encounter the problem on 32-bit systems. In fact, on 64-bit systems
it is not actually possible to construct LinSpace{Float64} objects
whose length cannot be represented as an Int. The issue does exist
for FloatRange on 64-bit systems, however. One possible solution is
to introduce length(T,x) that gives lengths in a particular type and
just define length(x) as length(Int,x) as the default behavior.
  • Loading branch information
StefanKarpinski committed Apr 13, 2015
1 parent 2a130b7 commit aa78037
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
4 changes: 2 additions & 2 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function linspace{T<:FloatingPoint}(start::T, stop::T, len::T)
s = convert(T,n*e)
if isinf(a*n) || isinf(c*n)
s, p = frexp(s)
p = one(p) << p
p = oftype(s,2)^p
a /= p; c /= p
end
if a*n/s == start && c*n/s == stop
Expand All @@ -211,7 +211,7 @@ function linspace{T<:FloatingPoint}(start::T, stop::T, len::T)
a, c, s = start, stop, n
if isinf(a*n) || isinf(c*n)
s, p = frexp(s)
p = one(p) << p
p = oftype(s,2)^p
a /= p; c /= p
end
if a*n/s == start && c*n/s == stop
Expand Down
14 changes: 8 additions & 6 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,15 @@ for T = (Float32, Float64)
@test [linspace(a,-b,3);] == [a,(a-b)/2,-b]
for c = maxintfloat(T)-3:maxintfloat(T)
s = linspace(-a,b,c)
@test first(s) == -a
@test last(s) == b
@test length(s) == c
@test first(s) == -a
@test last(s) == b
c <= typemax(Int) && @test length(s) == c
@test s.len == c
s = linspace(a,-b,c)
@test first(s) == a
@test last(s) == -b
@test length(s) == c
@test first(s) == a
@test last(s) == -b
c <= typemax(Int) && @test length(s) == c
@test s.len == c
end
b = prevfloat(b)
end
Expand Down

0 comments on commit aa78037

Please sign in to comment.