Skip to content

Commit 737dd7c

Browse files
committed
Make LinSpace generic and endpoint-preserving. Fixes #14420.
Implement StepRangeHiLo Split out TwicePrecision utilities from basic Range functionality Define AbstractTime numeric traits Needed for tests with new ranges on 32-bit CPUs New range performance optimizations Add StepRangeLen to stdlib docs [ci skip] Misc cleanups for range code Fix printing bug with range of non-scalars Simpler implementation of unsafe_getindex for LinSpace Conflicts: base/dates/types.jl base/deprecated.jl base/exports.jl base/float.jl base/operators.jl base/range.jl doc/src/stdlib/math.md test/ranges.jl
1 parent 6a1e339 commit 737dd7c

16 files changed

+1128
-289
lines changed

base/abstractarray.jl

+2-4
Original file line numberDiff line numberDiff line change
@@ -729,11 +729,9 @@ full(x::AbstractArray) = x
729729

730730
map{T<:Real}(::Type{T}, r::StepRange) = T(r.start):T(r.step):T(last(r))
731731
map{T<:Real}(::Type{T}, r::UnitRange) = T(r.start):T(last(r))
732-
map{T<:AbstractFloat}(::Type{T}, r::FloatRange) = FloatRange(T(r.start), T(r.step), r.len, T(r.divisor))
732+
map{T<:AbstractFloat}(::Type{T}, r::StepRangeLen) = convert(StepRangeLen{T}, r)
733733
function map{T<:AbstractFloat}(::Type{T}, r::LinSpace)
734-
new_len = T(r.len)
735-
new_len == r.len || error("$r: too long for $T")
736-
LinSpace(T(r.start), T(r.stop), new_len, T(r.divisor))
734+
LinSpace(T(r.start), T(r.stop), length(r))
737735
end
738736

739737
## unsafe/pointer conversions ##

base/coreimg.jl

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typealias Cint Int32
2222
typealias Csize_t UInt
2323
include("promotion.jl")
2424
include("tuple.jl")
25+
include("traits.jl")
2526
include("range.jl")
2627
include("expr.jl")
2728
include("error.jl")

base/dates/types.jl

+3
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,6 @@ Base.isless(x::Date,y::Date) = isless(value(x),value(y))
240240
Base.isless(x::DateTime,y::DateTime) = isless(value(x),value(y))
241241
Base.isless(x::TimeType,y::TimeType) = isless(promote(x,y)...)
242242
==(x::TimeType,y::TimeType) = ===(promote(x,y)...)
243+
244+
(::Type{Base.TypeOrder}){T<:AbstractTime}(::Type{T}) = Base.HasOrder()
245+
(::Type{Base.TypeArithmetic}){T<:AbstractTime}(::Type{T}) = Base.ArithmeticOverflows()

base/deprecated.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -785,4 +785,5 @@ const _oldstyle_array_vcat_ = false
785785

786786
Filesystem.stop_watching(stream::Filesystem._FDWatcher) = depwarn("stop_watching(::_FDWatcher) should not be used.", :stop_watching)
787787

788-
# End deprecations scheduled for 0.6
788+
# FloatRange replaced by StepRangeLen
789+
@deprecate FloatRange{T}(start::T, step, len, den) Base.floatrange(T, start, step, len, den)

base/exports.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export
6161
Factorization,
6262
FileMonitor,
6363
Filter,
64-
FloatRange,
64+
StepRangeLen,
6565
Future,
6666
Hermitian,
6767
UniformScaling,

base/float.jl

+25-4
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,29 @@ significand_mask(::Type{Float32}) = 0x007f_ffff
525525
@pure exponent_bits{T<:AbstractFloat}(::Type{T}) = sizeof(T)*8 - significand_bits(T) - 1
526526
@pure exponent_bias{T<:AbstractFloat}(::Type{T}) = Int(exponent_one(T) >> significand_bits(T))
527527

528+
## TwicePrecision utilities
529+
# The numeric constants are half the number of bits in the mantissa
530+
for (F, T, n) in ((Float16, UInt16, 5), (Float32, UInt32, 12), (Float64, UInt64, 26))
531+
@eval begin
532+
function truncbits(x::$F, nb)
533+
@_inline_meta
534+
truncmask(x, typemax($T) << nb)
535+
end
536+
function truncmask(x::$F, mask)
537+
@_inline_meta
538+
box($F, unbox($T, mask & box($T, unbox($F, x))))
539+
end
540+
function splitprec(x::$F)
541+
@_inline_meta
542+
hi = truncmask(x, typemax($T) << $n)
543+
hi, x-hi
544+
end
545+
end
546+
end
547+
548+
truncbits(x, nb) = x
549+
truncmask(x, mask) = x
550+
528551
## Array operations on floating point numbers ##
529552

530553
float{T<:AbstractFloat}(A::AbstractArray{T}) = A
@@ -540,11 +563,9 @@ for fn in (:float,:big)
540563
@eval begin
541564
$fn(r::StepRange) = $fn(r.start):$fn(r.step):$fn(last(r))
542565
$fn(r::UnitRange) = $fn(r.start):$fn(last(r))
543-
$fn(r::FloatRange) = FloatRange($fn(r.start), $fn(r.step), r.len, $fn(r.divisor))
566+
$fn(r::StepRangeLen) = StepRangeLen($fn(r.ref), $fn(r.step), length(r), r.offset)
544567
function $fn(r::LinSpace)
545-
new_len = $fn(r.len)
546-
new_len == r.len || error(string(r, ": too long for ", $fn))
547-
LinSpace($fn(r.start), $fn(r.stop), new_len, $fn(r.divisor))
568+
LinSpace($fn(r.start), $fn(r.stop), length(r))
548569
end
549570
end
550571
end

base/mpfr.jl

+5
Original file line numberDiff line numberDiff line change
@@ -894,4 +894,9 @@ function Base.deepcopy_internal(x::BigFloat, stackdict::ObjectIdDict)
894894
return y
895895
end
896896

897+
function lerpi(j::Integer, d::Integer, a::BigFloat, b::BigFloat)
898+
t = BigFloat(j)/d
899+
fma(t, b, fma(-t, a, a))
900+
end
901+
897902
end #module

base/operators.jl

+14-30
Original file line numberDiff line numberDiff line change
@@ -508,45 +508,29 @@ for f in (:+, :-)
508508
range($f(first(r1),first(r2)), $f(step(r1),step(r2)), r1l)
509509
end
510510

511-
function $f{T<:AbstractFloat}(r1::FloatRange{T}, r2::FloatRange{T})
511+
function $f{T}(r1::LinSpace{T}, r2::LinSpace{T})
512512
len = r1.len
513513
(len == r2.len ||
514514
throw(DimensionMismatch("argument dimensions must match")))
515-
divisor1, divisor2 = r1.divisor, r2.divisor
516-
if divisor1 == divisor2
517-
FloatRange{T}($f(r1.start,r2.start), $f(r1.step,r2.step),
518-
len, divisor1)
519-
else
520-
d1 = Int(divisor1)
521-
d2 = Int(divisor2)
522-
d = lcm(d1,d2)
523-
s1 = div(d,d1)
524-
s2 = div(d,d2)
525-
FloatRange{T}($f(r1.start*s1, r2.start*s2),
526-
$f(r1.step*s1, r2.step*s2), len, d)
527-
end
528-
end
529-
530-
function $f{T<:AbstractFloat}(r1::LinSpace{T}, r2::LinSpace{T})
531-
len = r1.len
532-
(len == r2.len ||
533-
throw(DimensionMismatch("argument dimensions must match")))
534-
divisor1, divisor2 = r1.divisor, r2.divisor
535-
if divisor1 == divisor2
536-
LinSpace{T}($f(r1.start, r2.start), $f(r1.stop, r2.stop),
537-
len, divisor1)
538-
else
539-
linspace(convert(T, $f(first(r1), first(r2))),
540-
convert(T, $f(last(r1), last(r2))), len)
541-
end
515+
linspace(convert(T, $f(first(r1), first(r2))),
516+
convert(T, $f(last(r1), last(r2))), len)
542517
end
543518

544-
$f(r1::Union{FloatRange, OrdinalRange, LinSpace},
545-
r2::Union{FloatRange, OrdinalRange, LinSpace}) =
519+
$f(r1::Union{StepRangeLen, OrdinalRange, LinSpace},
520+
r2::Union{StepRangeLen, OrdinalRange, LinSpace}) =
546521
$f(promote(r1, r2)...)
547522
end
548523
end
549524

525+
function +{T,S}(r1::StepRangeLen{T,S}, r2::StepRangeLen{T,S})
526+
len = length(r1)
527+
(len == length(r2) ||
528+
throw(DimensionMismatch("argument dimensions must match")))
529+
StepRangeLen(first(r1)+first(r2), step(r1)+step(r2), len)
530+
end
531+
532+
-(r1::StepRangeLen, r2::StepRangeLen) = +(r1, -r2)
533+
550534
# vectorization
551535

552536
macro vectorize_1arg(S,f)

0 commit comments

Comments
 (0)