diff --git a/src/FixedPointDecimals.jl b/src/FixedPointDecimals.jl index e329474..788f7c9 100644 --- a/src/FixedPointDecimals.jl +++ b/src/FixedPointDecimals.jl @@ -300,10 +300,17 @@ end for remfn in [:rem, :mod, :mod1, :min, :max] @eval $remfn(x::T, y::T) where {T <: FD} = reinterpret(T, $remfn(x.i, y.i)) end -for divfn in [:div, :fld, :fld1] +# TODO: When we upgrade to a min julia version >=1.4 (i.e Julia 2.0), this block can be +# dropped in favor of three-argument `div`, below. +for divfn in [:div, :fld, :fld1, :cld] # div(x.i, y.i) eliminates the scaling coefficient, so we call the FD constructor. # We don't need any widening logic, since we won't be multiplying by the coefficient. - @eval $divfn(x::T, y::T) where {T <: FD} = T($divfn(x.i, y.i)) + @eval Base.$divfn(x::T, y::T) where {T <: FD} = T($divfn(x.i, y.i)) +end +if VERSION >= v"1.4.0-" + # div(x.i, y.i) eliminates the scaling coefficient, so we call the FD constructor. + # We don't need any widening logic, since we won't be multiplying by the coefficient. + Base.div(x::T, y::T, r::RoundingMode) where {T <: FD} = T(div(x.i, y.i, r)) end convert(::Type{AbstractFloat}, x::FD) = convert(floattype(typeof(x)), x) diff --git a/test/runtests.jl b/test/runtests.jl index 038441c..33fe0ac 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -536,6 +536,20 @@ end @test one(FD{Int32, 2}) รท one(FD{Int64, 6}) isa FD{Int64, 6} end + + @testset "div with rounding modes" begin + if VERSION >= v"1.4.0-" + @testset for x in keyvalues[FD2] + # TODO: Test RoundFromZero -- https://github.com/JuliaLang/julia/issues/34519 + for R in (RoundToZero, RoundUp, RoundDown, RoundNearest, RoundNearestTiesAway) + @test div(x, 2one(x), R) === div(x, 2, R) === FD2(div(x.i, FD2(2).i, R)) + end + end + end + @testset for x in keyvalues[FD2], f in (fld, cld, fld1, div) + @test f(x, 2one(x)) === f(x, 2) === FD2(f(x.i, FD2(2).i)) + end + end end @testset "abs, sign" begin