Skip to content

Commit

Permalink
improve float ranges, for #2333
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Feb 17, 2013
1 parent fc24db9 commit d337cac
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
2 changes: 1 addition & 1 deletion base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ iround(::Type{Uint128}, x::Float32) = convert(Uint128,round(x))
iround(::Type{Uint128}, x::Float64) = convert(Uint128,round(x))

# this is needed very early because it is used by Range and colon
floor(x::Float64) = ccall((:floor, Base.libm_name), Float64, (Float64,), x)
round(x::Float64) = ccall((:round, Base.libm_name), Float64, (Float64,), x)

iceil(x::FloatingPoint) = itrunc(ceil(x)) # TODO: fast primitive for iceil
ifloor(x::FloatingPoint) = itrunc(floor(x)) # TOOD: fast primitive for ifloor
Expand Down
8 changes: 4 additions & 4 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ for f in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh, :log, :log2, :log10,
end
end

for f in (:logb, :expm1, :ceil, :trunc, :round, :significand) # :rint, :nearbyint
for f in (:logb, :expm1, :ceil, :trunc, :floor, :significand) # :rint, :nearbyint
@eval begin
($f)(x::Float64) = ccall(($(string(f)),libm), Float64, (Float64,), x)
($f)(x::Float32) = ccall(($(string(f,"f")),libm), Float32, (Float32,), x)
Expand All @@ -121,9 +121,9 @@ for f in (:logb, :expm1, :ceil, :trunc, :round, :significand) # :rint, :nearbyin
end
end

floor(x::Float32) = ccall((:floorf, libm), Float32, (Float32,), x)
floor(x::Real) = floor(float(x))
@vectorize_1arg Real floor
round(x::Float32) = ccall((:roundf, libm), Float32, (Float32,), x)
round(x::Real) = round(float(x))
@vectorize_1arg Real round

atan2(x::Real, y::Real) = atan2(float64(x), float64(y))

Expand Down
36 changes: 28 additions & 8 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,38 @@ colon(start::Char, stop::Char) =
OrdinalRange(start, 1, max(0, stop-start+1))

function colon{T<:Real}(start::T, step::T, stop::T)
len = (stop-start)/step
if len >= typemax(Int)
error("Range: length ",len," is too large")
if (step<0) != (stop<start)
len = 0
else
nf = (stop-start)/step + 1
if T <: FloatingPoint
n = round(nf)
if abs(n-nf) < eps(n)*3
# adjust step to try to hit stop exactly
step = (stop-start)/(n-1)
end
len = itrunc(n)
else
n = nf
len = iround(n)
end
if n >= typemax(Int)
error("Range: length ",n," is too large")
end
end
Range(start, step, max(0, ifloor(len)+1))
Range(start, step, len)
end
function colon{T<:Real}(start::T, stop::T)
len = stop-start
if len >= typemax(Int)
error("Range: length ",len," is too large")
if stop < start
len = 0
else
n = round(stop-start+1)
if n >= typemax(Int)
error("Range: length ",n," is too large")
end
len = itrunc(n)
end
Range1(start, max(0, ifloor(len)+1))
Range1(start, len)
end

colon(start::Real, step::Real, stop::Real) = colon(promote(start, step, stop)...)
Expand Down
4 changes: 4 additions & 0 deletions test/corelib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ r = [5:-1:1]
@test r[4]==2
@test r[5]==1

@test length(.1:.1:.3) == 3
@test length(1.1:1.1:3.3) == 3
@test length(1.1:1.3:3) == 2

let
span = 5:20
r = -7:3:42
Expand Down

0 comments on commit d337cac

Please sign in to comment.