Skip to content

Commit

Permalink
fix incorrect mod rounding
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyrne committed Oct 28, 2014
1 parent 7fdc860 commit 0d193e4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
12 changes: 11 additions & 1 deletion base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,17 @@ rem(x::Float64, y::Float64) = box(Float64,rem_float(unbox(Float64,x),unbox(Float

cld{T<:FloatingPoint}(x::T, y::T) = -fld(-x,y)

mod{T<:FloatingPoint}(x::T, y::T) = rem(y+rem(x,y),y)
function mod{T<:FloatingPoint}(x::T, y::T)
r = rem(x,y)
if r == 0
copysign(r,y)
elseif (r > 0) $ (y > 0)
r+y
else
r
end
end


## floating point comparisons ##

Expand Down
32 changes: 15 additions & 17 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2519,22 +2519,23 @@ Mathematical Operators

Element-wise exponentiation operator.

.. function:: div(a,b)
÷(a,b)
.. function:: div(x, y)
÷(x, y)

Compute a/b, truncating to an integer.
The quotient from Euclidean division. Computes ``x/y``, truncated to an integer.

.. function:: fld(a,b)
.. function:: fld(x, y)

Largest integer less than or equal to a/b.
Largest integer less than or equal to ``x/y``.

.. function:: cld(a,b)
.. function:: cld(x, y)

Smallest integer larger than or equal to a/b.
Smallest integer larger than or equal to ``x/y``.

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

Modulus after division, returning in the range [0,m).
Modulus after division, returning in the range [0,``m``), if ``m`` is
positive, or (``m``,0] if ``m`` is negative.

.. function:: mod2pi(x)

Expand All @@ -2545,18 +2546,15 @@ Mathematical Operators
mod(x,2pi), which would compute the modulus of x relative to division by the
floating-point number 2pi.

.. function:: rem(x, m)
.. function:: rem(x, y)
%(x, y)

Remainder after division.
Remainder from Euclidean division, returning a value of the same sign
as``x``, and smaller in magnitude than ``y``. This value is always exact.

.. function:: divrem(x, y)

Returns ``(x/y, x%y)``.

.. _%:
.. function:: %(x, m)

Remainder after division. The operator form of ``rem``.
The quotient and remainder from Euclidean division. Equivalent to ``(x÷y, x%y)``.

.. function:: mod1(x,m)

Expand Down
4 changes: 4 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,10 @@ end
@test div(0.3,0.01) == 29.0
# see https://github.com/JuliaLang/julia/issues/3127

# issue #8831
@test rem(prevfloat(1.0),1.0) == prevfloat(1.0)
@test mod(prevfloat(1.0),1.0) == prevfloat(1.0)

# issue #3046
@test mod(int64(2),typemax(Int64)) == 2

Expand Down

0 comments on commit 0d193e4

Please sign in to comment.