Skip to content

Commit

Permalink
Merge pull request #22644 from angusmoore/anm/ranges-32bit-#22613
Browse files Browse the repository at this point in the history
Handle 32 bit architecture when creating float ranges (#22613)
  • Loading branch information
timholy authored Jul 12, 2017
2 parents 5eb4112 + 7f163ba commit f6e55a7
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 11 deletions.
10 changes: 9 additions & 1 deletion base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,15 @@ bswap
The largest integer losslessly representable by the given floating-point DataType `T`.
"""
maxintfloat
maxintfloat(T)

"""
maxintfloat(T, S)
The largest integer losslessly representable by the given floating-point DataType `T` that
also does not exceed the maximum integer representable by the integer DataType `S`.
"""
maxintfloat(T, S)

"""
delete!(collection, key)
Expand Down
1 change: 1 addition & 0 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ maxintfloat(::Type{Float64}) = 9007199254740992.
maxintfloat(::Type{Float32}) = Float32(16777216.)
maxintfloat(::Type{Float16}) = Float16(2048f0)
maxintfloat(x::T) where {T<:AbstractFloat} = maxintfloat(T)
maxintfloat(::Type{S}, ::Type{T}) where {S<:AbstractFloat, T<:Integer} = min(maxintfloat(S), S(typemax(T)))
maxintfloat() = maxintfloat(Float64)

isinteger(x::AbstractFloat) = (x - trunc(x) == 0)
Expand Down
10 changes: 5 additions & 5 deletions base/twiceprecision.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ end

function floatrange(a::AbstractFloat, st::AbstractFloat, len::Real, divisor::AbstractFloat)
T = promote_type(typeof(a), typeof(st), typeof(divisor))
m = maxintfloat(T)
m = maxintfloat(T, Int)
if abs(a) <= m && abs(st) <= m && abs(divisor) <= m
ia, ist, idivisor = round(Int, a), round(Int, st), round(Int, divisor)
if ia == a && ist == st && idivisor == divisor
Expand All @@ -131,7 +131,7 @@ function colon(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float6
if start_d != 0 && stop_d != 0 &&
T(start_n/start_d) == start && T(stop_n/stop_d) == stop
den = lcm(start_d, step_d) # use same denominator for start and step
m = maxintfloat(T)
m = maxintfloat(T, Int)
if den != 0 && abs(start*den) <= m && abs(step*den) <= m && # will round succeed?
rem(den, start_d) == 0 && rem(den, step_d) == 0 # check lcm overflow
start_n = round(Int, start*den)
Expand Down Expand Up @@ -167,7 +167,7 @@ function range(a::T, st::T, len::Integer) where T<:Union{Float16,Float32,Float64
if start_d != 0 && step_d != 0 &&
T(start_n/start_d) == a && T(step_n/step_d) == st
den = lcm(start_d, step_d)
m = maxintfloat(T)
m = maxintfloat(T, Int)
if abs(den*a) <= m && abs(den*st) <= m &&
rem(den, start_d) == 0 && rem(den, step_d) == 0
start_n = round(Int, den*a)
Expand Down Expand Up @@ -257,7 +257,7 @@ function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::Range{U}) where {T,R,S,U}
if start_d != 0 && step_d != 0 &&
U(start_n/start_d) == f && U(step_n/step_d) == s
den = lcm(start_d, step_d)
m = maxintfloat(T)
m = maxintfloat(T, Int)
if den != 0 && abs(f*den) <= m && abs(s*den) <= m &&
rem(den, start_d) == 0 && rem(den, step_d) == 0
start_n = round(Int, f*den)
Expand Down Expand Up @@ -326,7 +326,7 @@ function linspace(start::T, stop::T, len::Integer) where T<:Union{Float16,Float3
stop_n, stop_d = rat(stop)
if start_d != 0 && stop_d != 0
den = lcm(start_d, stop_d)
m = maxintfloat(T)
m = maxintfloat(T, Int)
if den != 0 && abs(den*start) <= m && abs(den*stop) <= m
start_n = round(Int, den*start)
stop_n = round(Int, den*stop)
Expand Down
10 changes: 7 additions & 3 deletions test/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ end

# maxintfloat

@test maxintfloat(Float16) == Float16(2048f0)
@test maxintfloat(Float16) === Float16(2048f0)
for elty in (Float16,Float32,Float64)
@test maxintfloat(rand(elty)) == maxintfloat(elty)
@test maxintfloat(rand(elty)) === maxintfloat(elty)
end
@test maxintfloat() == maxintfloat(Float64)
@test maxintfloat() === maxintfloat(Float64)
@test maxintfloat(Float64, Int32) === 2147483647.0
@test maxintfloat(Float32, Int32) === maxintfloat(Float32)
@test maxintfloat(Float64, Int16) === 32767.0
@test maxintfloat(Float64, Int64) === maxintfloat(Float64)

# isinteger
for elty in (Float16,Float32,Float64)
Expand Down
7 changes: 5 additions & 2 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,18 @@ for T = (Float32, Float64,), i = 1:2^15, n = 1:5
# FIXME: these fail some small portion of the time
@test_skip start == first(r)
@test_skip stop == last(r)
# FIXME: linspace construction fails on 32-bit
Sys.WORD_SIZE == 64 || continue
l = linspace(start,stop,n)
@test n == length(l)
# FIXME: these fail some small portion of the time
@test_skip start == first(l)
@test_skip stop == last(l)
end

# Inexact errors on 32 bit architectures. #22613
@test first(linspace(log(0.2), log(10.0), 10)) == log(0.2)
@test last(linspace(log(0.2), log(10.0), 10)) == log(10.0)
@test length(Base.floatrange(-3e9, 1.0, 1, 1.0)) == 1

# linspace & ranges with very small endpoints
for T = (Float32, Float64)
z = zero(T)
Expand Down

0 comments on commit f6e55a7

Please sign in to comment.