Skip to content

Commit 2e945b8

Browse files
committed
Merge pull request #14140 from eschnett/eschnett/mod1
Clean up mod1
2 parents 79356b8 + 958a566 commit 2e945b8

File tree

7 files changed

+83
-18
lines changed

7 files changed

+83
-18
lines changed

base/abstractarraymath.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,7 @@ function repeat{T}(A::Array{T};
231231
# "Project" outer repetitions into inner repetitions
232232
indices_in[t] = mod1(indices_out[t], inner_size_out[t])
233233
# Find inner repetitions using flooring division
234-
if inner[t] != 1
235-
indices_in[t] = fld1(indices_in[t], inner[t])
236-
end
234+
indices_in[t] = fld1(indices_in[t], inner[t])
237235
end
238236
index_in = sub2ind(size_in, indices_in...)
239237
R[index_out] = A[index_in]

base/deprecated.jl

+9
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,15 @@ end
873873
@deprecate chol(A::Number, ::Type{Val{:L}}) ctranspose(chol(A))
874874
@deprecate chol(A::AbstractMatrix, ::Type{Val{:L}}) ctranspose(chol(A))
875875

876+
# Number updates
877+
878+
# rem1 is inconsistent for x==0: The result should both have the same
879+
# sign as x, and should be non-zero.
880+
function rem1{T<:Real}(x::T, y::T)
881+
depwarn("`rem1(x,y)` is discontinued, as it cannot be defined consistently for `x==0`. Rewrite the expression using `mod1` instead.", :rem1)
882+
rem(x-1,y)+1
883+
end
884+
876885
# Filesystem module updates
877886

878887
@deprecate_binding FS Filesystem

base/docs/helpdb.jl

+28-6
Original file line numberDiff line numberDiff line change
@@ -3265,7 +3265,7 @@ tril!(M, k)
32653265
doc"""
32663266
divrem(x, y)
32673267
3268-
The quotient and remainder from Euclidean division. Equivalent to `(x÷y, x%y)`.
3268+
The quotient and remainder from Euclidean division. Equivalent to `(div(x,y), rem(x,y))` or `(x÷y, x%y)`.
32693269
"""
32703270
divrem
32713271

@@ -5266,6 +5266,8 @@ doc"""
52665266
%(x, y)
52675267
52685268
Remainder from Euclidean division, returning a value of the same sign as `x`, and smaller in magnitude than `y`. This value is always exact.
5269+
5270+
x == div(x,y)*y + rem(x,y)
52695271
"""
52705272
rem
52715273

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

56685670
doc"""
5669-
rem1(x,m)
5671+
rem1(x, y)
56705672
5671-
Remainder after division, returning in the range (0,m\]
5673+
(Deprecated.) Remainder after division, returning in the range `(0,y\]`
56725674
"""
56735675
rem1
56745676

@@ -8304,7 +8306,9 @@ procs(::SharedArray)
83048306
doc"""
83058307
mod(x, y)
83068308
8307-
Modulus after division, returning in the range \[0,`y`), if `y` is positive, or (`y`,0\] if `y` is negative.
8309+
Modulus after flooring division, returning in the range \[0,`y`), if `y` is positive, or (`y`,0\] if `y` is negative.
8310+
8311+
x == fld(x,y)*y + mod(x,y)
83088312
"""
83098313
mod
83108314

@@ -8461,12 +8465,30 @@ Matrix inverse
84618465
inv
84628466

84638467
doc"""
8464-
mod1(x,m)
8468+
fld1(x, y)
8469+
8470+
Flooring division, returning a value consistent with `mod1(x,y)`
8471+
8472+
x == fld(x,y)*y + mod(x,y)
8473+
8474+
x == (fld1(x,y)-1)*y + mod1(x,y)
8475+
"""
8476+
fld1
8477+
8478+
doc"""
8479+
mod1(x, y)
84658480
8466-
Modulus after division, returning in the range (0,m\]
8481+
Modulus after flooring division, returning a value in the range `(0,y\]`
84678482
"""
84688483
mod1
84698484

8485+
doc"""
8486+
fldmod1(x, y)
8487+
8488+
Return `(fld1(x,y), mod1(x,y))`
8489+
"""
8490+
fldmod1
8491+
84708492
doc"""
84718493
@assert cond [text]
84728494

base/exports.jl

+2
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ export
357357
factor,
358358
factorial,
359359
fld,
360+
fld1,
360361
fldmod,
362+
fldmod1,
361363
flipsign,
362364
float,
363365
tryparse,

base/operators.jl

+8-3
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,15 @@ const % = rem
149149
.%(x::Real, y::Real) = x%y
150150
const ÷ = div
151151

152-
# mod returns in [0,y) whereas mod1 returns in (0,y]
152+
# mod returns in [0,y) or (y,0] (for negative y),
153+
# whereas mod1 returns in (0,y] or [y,0)
153154
mod1{T<:Real}(x::T, y::T) = (m=mod(x,y); ifelse(m==0, y, m))
154-
rem1{T<:Real}(x::T, y::T) = rem(x-1,y)+1
155-
fld1{T<:Real}(x::T, y::T) = fld(x-1,y)+1
155+
fld1{T<:Real}(x::T, y::T) = (m=mod(x,y); fld(x-m,y))
156+
fldmod1{T<:Real}(x::T, y::T) = (fld1(x,y), mod1(x,y))
157+
# efficient version for integers
158+
mod1{T<:Integer}(x::T, y::T) = mod(x+y-T(1),y)+T(1)
159+
fld1{T<:Integer}(x::T, y::T) = fld(x+y-T(1),y)
160+
fldmod1{T<:Integer}(x::T, y::T) = (fld1(x,y), mod1(x,y))
156161

157162
# transpose
158163
transpose(x) = x

doc/stdlib/math.rst

+32-6
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ Mathematical Operators
135135

136136
.. Docstring generated from Julia source
137137
138-
Modulus after division, returning in the range [0,``y``\ ), if ``y`` is positive, or (``y``\ ,0] if ``y`` is negative.
138+
Modulus after flooring division, returning in the range [0,``y``\ ), if ``y`` is positive, or (``y``\ ,0] if ``y`` is negative.
139+
140+
.. code-block:: julia
141+
142+
x == fld(x,y)*y + mod(x,y)
139143
140144
.. function:: mod2pi(x)
141145

@@ -152,29 +156,51 @@ Mathematical Operators
152156
153157
Remainder from Euclidean division, returning a value of the same sign as ``x``\ , and smaller in magnitude than ``y``\ . This value is always exact.
154158

159+
.. code-block:: julia
160+
161+
x == div(x,y)*y + rem(x,y)
162+
155163
.. function:: divrem(x, y)
156164

157165
.. Docstring generated from Julia source
158166
159-
The quotient and remainder from Euclidean division. Equivalent to ``(x÷y, x%y)``\ .
167+
The quotient and remainder from Euclidean division. Equivalent to ``(div(x,y), rem(x,y))`` or ``(x÷y, x%y)``\ .
160168

161169
.. function:: fldmod(x, y)
162170

163171
.. Docstring generated from Julia source
164172
165173
The floored quotient and modulus after division. Equivalent to ``(fld(x,y), mod(x,y))``\ .
166174

167-
.. function:: mod1(x,m)
175+
.. function:: fld1(x, y)
176+
177+
.. Docstring generated from Julia source
178+
179+
Flooring division, returning a value consistent with ``mod1(x,y)``
180+
181+
.. code-block:: julia
182+
183+
x == fld(x,y)*y + mod(x,y)
184+
185+
x == (fld1(x,y)-1)*y + mod1(x,y)
186+
187+
.. function:: mod1(x, y)
188+
189+
.. Docstring generated from Julia source
190+
191+
Modulus after flooring division, returning a value in the range ``(0,y\]``
192+
193+
.. function:: fldmod1(x, y)
168194

169195
.. Docstring generated from Julia source
170196
171-
Modulus after division, returning in the range (0,m]
197+
Return ``(fld1(x,y), mod1(x,y))``
172198

173-
.. function:: rem1(x,m)
199+
.. function:: rem1(x, y)
174200

175201
.. Docstring generated from Julia source
176202
177-
Remainder after division, returning in the range (0,m]
203+
(Deprecated.) Remainder after division, returning in the range ``(0,y\]``
178204

179205
.. _//:
180206
.. function:: //(num, den)

test/numbers.jl

+3
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,9 @@ end
25302530
# test second branch, after all small primes in list have been searched
25312531
@test factor(10009 * Int128(1000000000000037)) == Dict(10009=>1,1000000000000037=>1)
25322532

2533+
@test all(x -> (m=mod1(x,3); 0<m<=3), -5:+5)
2534+
@test all(x -> x == (fld1(x,3)-1)*3 + mod1(x,3), -5:+5)
2535+
@test all(x -> fldmod1(x,3) == (fld1(x,3), mod1(x,3)), -5:+5)
25332536
#Issue #5570
25342537
@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]
25352538

0 commit comments

Comments
 (0)