Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up mod1 #14140

Merged
merged 1 commit into from
Dec 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions base/abstractarraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
9 changes: 9 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 28 additions & 6 deletions base/docs/helpdb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -5666,9 +5668,9 @@ The distance between `x` and the next larger representable floating-point value
eps(::AbstractFloat)

doc"""
rem1(x,m)
rem1(x, y)

Remainder after division, returning in the range (0,m\]
(Deprecated.) Remainder after division, returning in the range `(0,y\]`
"""
rem1

Expand Down Expand Up @@ -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,y)*y + mod(x,y)
"""
mod

Expand Down Expand Up @@ -8461,12 +8465,30 @@ Matrix inverse
inv

doc"""
mod1(x,m)
fld1(x, y)

Flooring division, returning a value consistent with `mod1(x,y)`

x == fld(x,y)*y + mod(x,y)

x == (fld1(x,y)-1)*y + mod1(x,y)
"""
fld1

doc"""
mod1(x, y)

Modulus after division, returning in the range (0,m\]
Modulus after flooring division, returning a value in the range `(0,y\]`
"""
mod1

doc"""
fldmod1(x, y)

Return `(fld1(x,y), mod1(x,y))`
"""
fldmod1

doc"""
@assert cond [text]

Expand Down
2 changes: 2 additions & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,9 @@ export
factor,
factorial,
fld,
fld1,
fldmod,
fldmod1,
flipsign,
float,
tryparse,
Expand Down
11 changes: 8 additions & 3 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 32 additions & 6 deletions doc/stdlib/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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,y)*y + mod(x,y)

.. function:: mod2pi(x)

Expand All @@ -152,29 +156,51 @@ 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)

.. Docstring generated from Julia source

The floored quotient and modulus after division. Equivalent to ``(fld(x,y), mod(x,y))``\ .

.. function:: mod1(x,m)
.. function:: fld1(x, y)

.. Docstring generated from Julia source

Flooring division, returning a value consistent with ``mod1(x,y)``

.. code-block:: julia

x == fld(x,y)*y + mod(x,y)

x == (fld1(x,y)-1)*y + mod1(x,y)

.. function:: mod1(x, y)

.. Docstring generated from Julia source

Modulus after flooring division, returning a value in the range ``(0,y\]``

.. function:: fldmod1(x, y)

.. Docstring generated from Julia source

Modulus after division, returning in the range (0,m]
Return ``(fld1(x,y), mod1(x,y))``

.. function:: rem1(x,m)
.. function:: rem1(x, y)

.. Docstring generated from Julia source

Remainder after division, returning in the range (0,m]
(Deprecated.) Remainder after division, returning in the range ``(0,y\]``

.. _//:
.. function:: //(num, den)
Expand Down
3 changes: 3 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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<m<=3), -5:+5)
@test all(x -> 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]

Expand Down