diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index 7fc7a868187a3..a924a083eddd9 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -231,9 +231,7 @@ function repeat{T}(A::Array{T}; # "Project" outer repetitions into inner repetitions indices_in[t] = mod1(indices_out[t], inner_size_out[t]) # Find inner repetitions using flooring division - if inner[t] != 1 - indices_in[t] = fld1(indices_in[t], inner[t]) - end + indices_in[t] = fld1(indices_in[t], inner[t]) end index_in = sub2ind(size_in, indices_in...) R[index_out] = A[index_in] diff --git a/base/deprecated.jl b/base/deprecated.jl index 8bcf077b5c6e3..9879c934bbc32 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -873,6 +873,15 @@ end @deprecate chol(A::Number, ::Type{Val{:L}}) ctranspose(chol(A)) @deprecate chol(A::AbstractMatrix, ::Type{Val{:L}}) ctranspose(chol(A)) +# Number updates + +# rem1 is inconsistent for x==0: The result should both have the same +# sign as x, and should be non-zero. +function rem1{T<:Real}(x::T, y::T) + depwarn("`rem1(x,y)` is discontinued, as it cannot be defined consistently for `x==0`. Rewrite the expression using `mod1` instead.", :rem1) + rem(x-1,y)+1 +end + # Filesystem module updates @deprecate_binding FS Filesystem diff --git a/base/docs/helpdb.jl b/base/docs/helpdb.jl index 31774c438daf4..fda09169f1be4 100644 --- a/base/docs/helpdb.jl +++ b/base/docs/helpdb.jl @@ -3265,7 +3265,7 @@ tril!(M, k) doc""" divrem(x, y) -The quotient and remainder from Euclidean division. Equivalent to `(x÷y, x%y)`. +The quotient and remainder from Euclidean division. Equivalent to `div(x,y), rem(x,y))` or `(x÷y, x%y)`. """ divrem @@ -5266,6 +5266,8 @@ doc""" %(x, y) Remainder from Euclidean division, returning a value of the same sign as `x`, and smaller in magnitude than `y`. This value is always exact. + + x == div(x,y)*y + rem(x,y) """ rem @@ -5666,9 +5668,9 @@ The distance between `x` and the next larger representable floating-point value eps(::AbstractFloat) doc""" - rem1(x,m) + rem1(x, m) -Remainder after division, returning in the range (0,m\] +(Deprecated.) Remainder after division, returning in the range `(0,m\]` """ rem1 @@ -8304,7 +8306,9 @@ procs(::SharedArray) doc""" mod(x, y) -Modulus after division, returning in the range \[0,`y`), if `y` is positive, or (`y`,0\] if `y` is negative. +Modulus after flooring division, returning in the range \[0,`y`), if `y` is positive, or (`y`,0\] if `y` is negative. + + x == fld(x,m)*m + mod(x,m) """ mod @@ -8461,12 +8465,30 @@ Matrix inverse inv doc""" - mod1(x,m) + fld1(x, m) + +Flooring division, returning a value consistent with `mod1(x,m)` + + x == fld(x,m)*m + mod(x,m) + + x == (fld1(x,m)-1)*m + mod1(x,m) +""" +fld1 + +doc""" + mod1(x, m) -Modulus after division, returning in the range (0,m\] +Modulus after flooring division, returning a value in the range `(0,m\]` """ mod1 +doc""" + fldmod1(x, m) + +Return `(fld1(x,m), mod1(x,m))` +""" +fldmod1 + doc""" @assert cond [text] diff --git a/base/exports.jl b/base/exports.jl index 4e224daded800..e1d999b636925 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -357,7 +357,9 @@ export factor, factorial, fld, + fld1, fldmod, + fldmod1, flipsign, float, tryparse, diff --git a/base/operators.jl b/base/operators.jl index 10e5a5982abef..796090e13aee9 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -149,10 +149,15 @@ const % = rem .%(x::Real, y::Real) = x%y const ÷ = div -# mod returns in [0,y) whereas mod1 returns in (0,y] +# mod returns in [0,y) or (y,0] (for negative y), +# whereas mod1 returns in (0,y] or [y,0) mod1{T<:Real}(x::T, y::T) = (m=mod(x,y); ifelse(m==0, y, m)) -rem1{T<:Real}(x::T, y::T) = rem(x-1,y)+1 -fld1{T<:Real}(x::T, y::T) = fld(x-1,y)+1 +fld1{T<:Real}(x::T, y::T) = (m=mod(x,y); fld(x-m,y)) +fldmod1{T<:Real}(x::T, y::T) = (fld1(x,y), mod1(x,y)) +# efficient version for integers +mod1{T<:Integer}(x::T, y::T) = mod(x+y-T(1),y)+T(1) +fld1{T<:Integer}(x::T, y::T) = fld(x+y-T(1),y) +fldmod1{T<:Integer}(x::T, y::T) = (fld1(x,y), mod1(x,y)) # transpose transpose(x) = x diff --git a/doc/stdlib/math.rst b/doc/stdlib/math.rst index a9bb3d784ac7b..f16cb565b371f 100644 --- a/doc/stdlib/math.rst +++ b/doc/stdlib/math.rst @@ -135,7 +135,11 @@ Mathematical Operators .. Docstring generated from Julia source - Modulus after division, returning in the range [0,``y``\ ), if ``y`` is positive, or (``y``\ ,0] if ``y`` is negative. + Modulus after flooring division, returning in the range [0,``y``\ ), if ``y`` is positive, or (``y``\ ,0] if ``y`` is negative. + + .. code-block:: julia + + x == fld(x,m)*m + mod(x,m) .. function:: mod2pi(x) @@ -152,11 +156,15 @@ Mathematical Operators Remainder from Euclidean division, returning a value of the same sign as ``x``\ , and smaller in magnitude than ``y``\ . This value is always exact. + .. code-block:: julia + + x == div(x,y)*y + rem(x,y) + .. function:: divrem(x, y) .. Docstring generated from Julia source - The quotient and remainder from Euclidean division. Equivalent to ``(x÷y, x%y)``\ . + The quotient and remainder from Euclidean division. Equivalent to ``div(x,y), rem(x,y))`` or ``(x÷y, x%y)``\ . .. function:: fldmod(x, y) @@ -164,11 +172,29 @@ Mathematical Operators The floored quotient and modulus after division. Equivalent to ``(fld(x,y), mod(x,y))``\ . +.. function:: fld1(x,m) + + .. Docstring generated from Julia source + + Flooring division, returning a value consistent with mod1(x,m) + + .. code-block:: julia + + x == fld(x,m)*m + mod(x,m) + + x == (fld1(x,m)-1)*m + mod1(x,m) + .. function:: mod1(x,m) .. Docstring generated from Julia source - Modulus after division, returning in the range (0,m] + Modulus after flooring division, returning a value in the range (0,m] + +.. function:: fldmod1(x,m) + + .. Docstring generated from Julia source + + Return (fld1(x,m), mod1(x,m)) .. function:: rem1(x,m) diff --git a/test/numbers.jl b/test/numbers.jl index db0222a942fac..ef332a16181f0 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -2530,6 +2530,9 @@ end # test second branch, after all small primes in list have been searched @test factor(10009 * Int128(1000000000000037)) == Dict(10009=>1,1000000000000037=>1) +@test all(x -> (m=mod1(x,3); 0 x == (fld1(x,3)-1)*3 + mod1(x,3), -5:+5) +@test all(x -> fldmod1(x,3) == (fld1(x,3), mod1(x,3)), -5:+5) #Issue #5570 @test map(x -> Int(mod1(UInt(x),UInt(5))), 0:15) == [5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]