Skip to content

Commit

Permalink
Divrem speedup and tests (#39045)
Browse files Browse the repository at this point in the history
fixes #22219
  • Loading branch information
r7rohan authored Nov 18, 2021
1 parent edea1de commit 616de75
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
21 changes: 21 additions & 0 deletions base/div.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ julia> divrem(7,3)
```
"""
divrem(x, y) = divrem(x, y, RoundToZero)


function divrem(a, b, r::RoundingMode)
if r === RoundToZero
# For compat. Remove in 2.0.
Expand All @@ -167,6 +169,25 @@ function divrem(a, b, r::RoundingMode)
(div(a, b, r), rem(a, b, r))
end
end
#avoids calling rem for Integers-Integers (all modes),
#a-d*b not precise for Floats - AbstractFloat, AbstractIrrational. Rationals are still slower
function divrem(a::Integer, b::Integer, r::Union{typeof(RoundUp),
typeof(RoundDown),
typeof(RoundToZero)})
if r === RoundToZero
# For compat. Remove in 2.0.
d = div(a, b)
(d, a - d*b)
elseif r === RoundDown
# For compat. Remove in 2.0.
d = fld(a, b)
(d, a - d*b)
elseif r === RoundUp
# For compat. Remove in 2.0.
d = div(a, b, r)
(d, a - d*b)
end
end
function divrem(x::Integer, y::Integer, rnd::typeof(RoundNearest))
(q, r) = divrem(x, y)
if x >= 0
Expand Down
35 changes: 35 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2549,6 +2549,41 @@ end
end
end

@testset "divrem rounded" begin
#rounded Floats
for T in (Float16, Float32, Float64, BigFloat)
@test divrem(T(1.5), T(2), RoundToZero)[2] == 1.5
@test divrem(T(1.5), T(2), RoundNearest)[2] == -0.5
@test divrem(T(1.5), T(2), RoundDown)[2] == 1.5
@test divrem(T(1.5), T(2), RoundUp)[2] == -0.5
@test divrem(T(-1.5), T(2), RoundToZero)[2] == -1.5
@test divrem(T(-1.5), T(2), RoundNearest)[2] == 0.5
@test divrem(T(-1.5), T(2), RoundDown)[2] == 0.5
@test divrem(T(-1.5), T(2), RoundUp)[2] == -1.5
end
#rounded Integers
for (a, b) in (
(3, 2),
(5, 3),
(-3, 2),
(5, 2),
(-5, 2),
(-5, 3),
(5, -3))
for sign in (+1, -1)
(a, b) = (a*sign, b*sign)
@test divrem(a, b, RoundNearest) == (div(a, b, RoundNearest),rem(a, b, RoundNearest))
end
end

a = 122322388883338838388383888823233122323
b = 343443
c = 122322388883338838388383888823233122333
@test divrem(a, b) == (div(a,b), rem(a,b))
@test divrem(a, c) == (div(a,c), rem(a,c))
@test divrem(a,-(a-20), RoundDown) == (div(a,-(a-20), RoundDown), rem(a,-(a-20), RoundDown))
end

@testset "rem2pi $T" for T in (Float16, Float32, Float64, BigFloat)
@test rem2pi(T(1), RoundToZero) == 1
@test rem2pi(T(1), RoundNearest) == 1
Expand Down

0 comments on commit 616de75

Please sign in to comment.