Skip to content

Commit 2f062ac

Browse files
committed
Fix methods ambiguities
1 parent 93cec87 commit 2f062ac

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/FixedPointDecimals.jl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ function Base.widemul(x::FD{T, f}, y::Integer) where {T, f}
123123
reinterpret(FD{typeof(i), f}, i)
124124
end
125125
Base.widemul(x::Integer, y::FD) = widemul(y, x)
126+
# needed to avoid ambiguities
127+
function Base.widemul(x::FD{T, f}, y::Bool) where {T, f}
128+
i = widemul(x.i, y)
129+
reinterpret(FD{typeof(i), f}, i)
130+
end
131+
Base.widemul(x::Bool, y::FD) = widemul(y, x)
126132

127133
"""
128134
_round_to_even(quotient, remainder, divisor)
@@ -239,13 +245,20 @@ for fn in [:trunc, :floor, :ceil]
239245
@eval (Base.$fn(::Type{TI}, x::FD)::TI) where {TI <: Integer} = $fn(x)
240246

241247
# round/trunc/ceil/flooring to FD; generic
242-
@eval function Base.$fn(::Type{FD{T, f}}, x::Real) where {T, f}
248+
@eval function $(Symbol(:_, fn))(::Type{FD{T, f}}, x::Real) where {T, f}
243249
powt = coefficient(FD{T, f})
244250
# Use machine Float64 if possible, but fall back to BigFloat if we need
245251
# more precision. 4f bits suffices.
246252
val = _apply_exact_float($(Symbol(fn, "mul")), T, x, powt)
247253
reinterpret(FD{T, f}, val)
248254
end
255+
@eval function Base.$fn(::Type{FD{T, f}}, x::Real) where {T, f}
256+
$(Symbol(:_, fn))(FD{T, f}, x)
257+
end
258+
# needed to avoid ambiguities
259+
@eval function Base.$fn(::Type{FD{T, f}}, x::Rational) where {T, f}
260+
$(Symbol(:_, fn))(FD{T, f}, x)
261+
end
249262
end
250263
function Base.round(::Type{TI}, x::FD, ::RoundingMode{:Nearest}=RoundNearest) where {TI <: Integer}
251264
convert(TI, round(x))::TI
@@ -254,9 +267,18 @@ function Base.round(::Type{FD{T, f}}, x::Real, ::RoundingMode{:Nearest}=RoundNea
254267
reinterpret(FD{T, f}, round(T, x * coefficient(FD{T, f})))
255268
end
256269

257-
# needed to avoid ambiguity
258-
function Base.round(::Type{FD{T, f}}, x::Rational, ::RoundingMode{:Nearest}=RoundNearest) where {T, f}
259-
reinterpret(FD{T, f}, round(T, x * coefficient(FD{T, f})))
270+
# needed to avoid ambiguities
271+
@static if Base.VERSION >= v"1.6"
272+
function Base.round(::Type{FD{T, f}}, x::Rational{Tr}, ::RoundingMode{:Nearest}=RoundNearest) where {T, Tr, f}
273+
reinterpret(FD{T, f}, round(T, x * coefficient(FD{T, f})))
274+
end
275+
function Base.round(::Type{FD{T, f}}, x::Rational{Bool}, ::RoundingMode{:Nearest}=RoundNearest) where {T, f}
276+
reinterpret(FD{T, f}, round(T, x * coefficient(FD{T, f})))
277+
end
278+
else
279+
function Base.round(::Type{FD{T, f}}, x::Rational, ::RoundingMode{:Nearest}=RoundNearest) where {T, f}
280+
reinterpret(FD{T, f}, round(T, x * coefficient(FD{T, f})))
281+
end
260282
end
261283

262284
# conversions and promotions
@@ -325,6 +347,8 @@ function Base.convert(::Type{TR}, x::FD{T, f}) where {TR <: Rational, T, f}
325347
end
326348

327349
(::Type{T})(x::FD) where {T<:Union{AbstractFloat,Integer,Rational}} = convert(T, x)
350+
# needed to avoid ambiguities
351+
Bool(x::FD) = x == 0 ? false : (x == 1 ? true : throw(InexactError(:Bool, Bool, x)))
328352

329353
Base.promote_rule(::Type{FD{T, f}}, ::Type{<:Integer}) where {T, f} = FD{T, f}
330354
Base.promote_rule(::Type{<:FD}, ::Type{TF}) where {TF <: AbstractFloat} = TF

test/runtests.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,4 +1045,17 @@ end
10451045
end
10461046
end
10471047

1048+
@testset "method ambiguities" begin
1049+
fd1 = FD{Int8, 1}(0.1)
1050+
fd2 = FD{Int, 1}(1.0)
1051+
1052+
@test widemul(fd1, false) == widemul(false, fd1) == FD{Int8, 1}(0.0)
1053+
@test ceil(FD{Int, 1}, 99 // 100) == fd2
1054+
@test round(FD{Int, 1}, true // true) == fd2
1055+
@test invoke(round, Tuple{Type{FD{Int, 1}}, Rational}, FD{Int, 1}, 99 // 100) == fd2
1056+
1057+
@test Bool(fd2)
1058+
@test_throws InexactError Bool(fd1)
1059+
end
1060+
10481061
end # global testset

0 commit comments

Comments
 (0)