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..97664740eb6e6 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, y)
 
-Remainder after division, returning in the range (0,m\]
+(Deprecated.) Remainder after division, returning in the range `(0,y\]`
 """
 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,y)*y + mod(x,y)
 """
 mod
 
@@ -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]
 
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..bf1e1a576e67e 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,y)*y + mod(x,y)
 
 .. 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,17 +172,35 @@ Mathematical Operators
 
    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)
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<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]