diff --git a/src/DecFP.jl b/src/DecFP.jl index d12c10d..c1695b6 100644 --- a/src/DecFP.jl +++ b/src/DecFP.jl @@ -184,6 +184,8 @@ for w in (32,64,128) Base.trunc(::Type{$Ti′}, x::$BID) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xint")), libbid), $Ti′, ($BID,), x), InexactError, INVALID | OVERFLOW) Base.floor(::Type{$Ti′}, x::$BID) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xfloor")), libbid), $Ti′, ($BID,), x), InexactError, INVALID | OVERFLOW) Base.ceil(::Type{$Ti′}, x::$BID) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xceil")), libbid), $Ti′, ($BID,), x), InexactError, INVALID | OVERFLOW) + Base.round(::Type{$Ti′}, x::$BID) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xrnint")), libbid), $Ti′, ($BID,), x), InexactError, INVALID | OVERFLOW) + Base.round(::Type{$Ti′}, x::$BID, ::RoundingMode{:NearestTiesAway}) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xrninta")), libbid), $Ti′, ($BID,), x), InexactError, INVALID | OVERFLOW) Base.convert(::Type{$Ti′}, x::$BID) = xchk(ccall(($(bidsym(w,"to_",lowercase(i′),"_xfloor")), libbid), $Ti′, ($BID,), x), InexactError) end end @@ -197,8 +199,20 @@ end # widths w Base.trunc(::Type{Integer}, x::DecimalFloatingPoint) = trunc(Int, x) Base.floor(::Type{Integer}, x::DecimalFloatingPoint) = floor(Int, x) Base.ceil(::Type{Integer}, x::DecimalFloatingPoint) = ceil(Int, x) +Base.round(::Type{Integer}, x::DecimalFloatingPoint) = round(Int, x) +Base.round(::Type{Integer}, x::DecimalFloatingPoint, ::RoundingMode{:NearestTiesAway}) = round(Int, x, RoundNearestTiesAway) Base.convert(::Type{Integer}, x::DecimalFloatingPoint) = convert(Int, x) +Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:Nearest}) = round(T, x) +function Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:NearestTiesUp}) + y = floor(T, x) + ifelse(x==y, y, copysign(floor(T, 2*x-y), x)) +end +Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:ToZero}) = trunc(T, x) +Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:FromZero}) = (x>=0 ? ceil(T, x) : floor(T, x)) +Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:Up}) = ceil(T, x) +Base.round{T<:Integer}(::Type{T}, x::DecimalFloatingPoint, ::RoundingMode{:Down}) = floor(T, x) + # the complex-sqrt function in base doesn't work for use, because it requires base-2 ldexp function Base.sqrt{T<:DecimalFloatingPoint}(z::Complex{T}) x, y = reim(z) diff --git a/test/runtests.jl b/test/runtests.jl index 7697e1e..1419892 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -85,7 +85,11 @@ for T in (Dec32, Dec64, Dec128) if Ti != Integer @test parse(T, "17") == T(Ti(17)) == Ti(17) == Ti(T(17)) end - @test trunc(Ti, T(4.5)) == floor(Ti, T(4.5)) == 4 == ceil(Ti, T(4.5)) - 1 + @test trunc(Ti, T(2.7)) === floor(Ti, T(2.7)) === round(Ti, T(2.7), RoundDown) === round(Ti, T(2.7), RoundToZero) === Ti(2) + @test ceil(Ti, T(2.3)) === round(Ti, T(2.3), RoundUp) === round(Ti, T(2.3), RoundFromZero) === Ti(3) + @test round(Ti, T(1.5)) === round(Ti, T(2.5)) === round(Ti, T(1.5), RoundNearest) === round(Ti, T(2.5), RoundNearest) === Ti(2) + @test round(Ti, T(2.5), RoundNearestTiesAway) === round(Ti, T(3.3), RoundNearestTiesAway) === Ti(3) + @test round(Ti, T(2.5), RoundNearestTiesUp) === round(Ti, T(3.3), RoundNearestTiesUp) === Ti(3) @test_throws InexactError convert(Ti, xd) @test_throws InexactError trunc(Ti, realmax(T)) @test_throws InexactError floor(Ti, realmax(T)) @@ -94,7 +98,12 @@ for T in (Dec32, Dec64, Dec128) @test parse(T, "-17") == T(Ti(-17)) == Ti(-17) == Ti(T(-17)) end if Ti <: Signed || Ti === Integer - @test floor(Ti, T(-4.5)) == -5 == trunc(Ti, T(-4.5)) - 1 == ceil(Ti, T(-4.5)) - 1 + @test trunc(Ti, T(-2.7)) === round(Ti, T(-2.7), RoundToZero) === Ti(-2) + @test floor(Ti, T(-2.3)) === round(Ti, T(-2.3), RoundDown) === round(Ti, T(-2.3), RoundFromZero) === Ti(-3) + @test ceil(Ti, T(-2.7)) === round(Ti, T(-2.7), RoundUp) === Ti(-2) + @test round(Ti, T(-1.5)) === round(Ti, T(-2.5)) === round(Ti, T(-1.5), RoundNearest) === round(Ti, T(-2.5), RoundNearest) === Ti(-2) + @test round(Ti, T(-2.5), RoundNearestTiesAway) === round(Ti, T(-3.3), RoundNearestTiesAway) === Ti(-3) + @test round(Ti, T(-1.5), RoundNearestTiesUp) === round(Ti, T(-0.7), RoundNearestTiesUp) === Ti(-1) @test_throws InexactError convert(Ti, yd) end end