Skip to content

Commit

Permalink
Change back to eltype
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesCranmer committed Nov 19, 2023
1 parent 1d14589 commit 84711c8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 24 deletions.
8 changes: 4 additions & 4 deletions src/disambiguities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ function Base.promote_rule(::Type{Bool}, ::Type{F}) where {F<:FixedRational}
return F
end
function Base.promote_rule(::Type{F}, ::Type{BigFloat}) where {F<:FixedRational}
return promote_type(Rational{num_type(F)}, BigFloat)
return promote_type(Rational{eltype(F)}, BigFloat)
end
function Base.promote_rule(::Type{BigFloat}, ::Type{F}) where {F<:FixedRational}
return promote_type(Rational{num_type(F)}, BigFloat)
return promote_type(Rational{eltype(F)}, BigFloat)
end
function Base.promote_rule(::Type{F}, ::Type{T}) where {F<:FixedRational,T<:AbstractIrrational}
return promote_type(Rational{num_type(F)}, T)
return promote_type(Rational{eltype(F)}, T)
end
function Base.promote_rule(::Type{T}, ::Type{F}) where {F<:FixedRational,T<:AbstractIrrational}
return promote_type(Rational{num_type(F)}, T)
return promote_type(Rational{eltype(F)}, T)
end

# Assorted calls found by Aqua:
Expand Down
39 changes: 19 additions & 20 deletions src/fixed_rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,25 @@ denom(x::FixedRational) = denom(typeof(x))
# Otherwise, we would have type instability.
val_denom(::Type{<:F}) where {F<:FixedRational} = Val(_denom(F))

num_type(::Type{<:FixedRational{T}}) where {T} = T
num_type(x::FixedRational) = num_type(typeof(x))
Base.eltype(::Type{<:FixedRational{T}}) where {T} = T

const DEFAULT_NUMERATOR_TYPE = Int32
const DEFAULT_DENOM = DEFAULT_NUMERATOR_TYPE(2^4 * 3^2 * 5^2 * 7)

(::Type{F})(x::F) where {F<:FixedRational} = x
(::Type{F})(x::F2) where {T,T2,den,F<:FixedRational{T,den},F2<:FixedRational{T2,den}} = unsafe_fixed_rational(x.num, num_type(F), val_denom(F))
(::Type{F})(x::Integer) where {F<:FixedRational} = unsafe_fixed_rational(x * denom(F), num_type(F), val_denom(F))
(::Type{F})(x::Rational) where {F<:FixedRational} = unsafe_fixed_rational(widemul(x.num, denom(F)) ÷ x.den, num_type(F), val_denom(F))
(::Type{F})(x::F2) where {T,T2,den,F<:FixedRational{T,den},F2<:FixedRational{T2,den}} = unsafe_fixed_rational(x.num, eltype(F), val_denom(F))
(::Type{F})(x::Integer) where {F<:FixedRational} = unsafe_fixed_rational(x * denom(F), eltype(F), val_denom(F))
(::Type{F})(x::Rational) where {F<:FixedRational} = unsafe_fixed_rational(widemul(x.num, denom(F)) ÷ x.den, eltype(F), val_denom(F))

Base.:*(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(widemul(l.num, r.num) ÷ denom(F), num_type(F), val_denom(F))
Base.:+(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l.num + r.num, num_type(F), val_denom(F))
Base.:-(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l.num - r.num, num_type(F), val_denom(F))
Base.:-(x::F) where {F<:FixedRational} = unsafe_fixed_rational(-x.num, num_type(F), val_denom(F))
Base.:*(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(widemul(l.num, r.num) ÷ denom(F), eltype(F), val_denom(F))
Base.:+(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l.num + r.num, eltype(F), val_denom(F))
Base.:-(l::F, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l.num - r.num, eltype(F), val_denom(F))
Base.:-(x::F) where {F<:FixedRational} = unsafe_fixed_rational(-x.num, eltype(F), val_denom(F))

Base.inv(x::F) where {F<:FixedRational} = unsafe_fixed_rational(widemul(denom(F), denom(F)) ÷ x.num, num_type(F), val_denom(F))
Base.inv(x::F) where {F<:FixedRational} = unsafe_fixed_rational(widemul(denom(F), denom(F)) ÷ x.num, eltype(F), val_denom(F))

Base.:*(l::F, r::Integer) where {F<:FixedRational} = unsafe_fixed_rational(l.num * r, num_type(F), val_denom(F))
Base.:*(l::Integer, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l * r.num, num_type(F), val_denom(F))
Base.:*(l::F, r::Integer) where {F<:FixedRational} = unsafe_fixed_rational(l.num * r, eltype(F), val_denom(F))
Base.:*(l::Integer, r::F) where {F<:FixedRational} = unsafe_fixed_rational(l * r.num, eltype(F), val_denom(F))

for comp in (:(==), :isequal, :<, :(isless), :<=)
@eval Base.$comp(x::F, y::F) where {F<:FixedRational} = $comp(x.num, y.num)
Expand All @@ -59,7 +58,7 @@ Base.isone(x::F) where {F<:FixedRational} = x.num == denom(F)
Base.isinteger(x::F) where {F<:FixedRational} = iszero(x.num % denom(F))

Rational{R}(x::F) where {R,F<:FixedRational} = Rational{R}(x.num, denom(F))
Rational(x::F) where {F<:FixedRational} = Rational{num_type(F)}(x)
Rational(x::F) where {F<:FixedRational} = Rational{eltype(F)}(x)
(::Type{AF})(x::F) where {AF<:AbstractFloat,F<:FixedRational} = convert(AF, x.num) / convert(AF, denom(F))
(::Type{I})(x::F) where {I<:Integer,F<:FixedRational} =
let
Expand All @@ -79,13 +78,13 @@ Base.decompose(x::F) where {T,F<:FixedRational{T}} = (x.num, zero(T), denom(F))
function Base.promote_rule(::Type{F1}, ::Type{F2}) where {F1<:FixedRational,F2<:FixedRational}
_denom(F1) == _denom(F2) ||
error("Refusing to promote `FixedRational` types with mixed denominators. Use `Rational` instead.")
return FixedRational{promote_type(num_type(F1), num_type(F2)), _denom(F1)}
return FixedRational{promote_type(eltype(F1), eltype(F2)), _denom(F1)}
end
function Base.promote_rule(::Type{F}, ::Type{Rational{T2}}) where {F<:FixedRational,T2}
return Rational{promote_type(num_type(F),T2)}
return Rational{promote_type(eltype(F),T2)}
end
function Base.promote_rule(::Type{Rational{T2}}, ::Type{F}) where {F<:FixedRational,T2}
return Rational{promote_type(num_type(F),T2)}
return Rational{promote_type(eltype(F),T2)}
end

# We want to consume integers
Expand All @@ -98,23 +97,23 @@ end

# Promotion with general types promotes like a rational
function Base.promote_rule(::Type{T}, ::Type{T2}) where {T2<:Real,T<:FixedRational}
return promote_type(Rational{num_type(T)}, T2)
return promote_type(Rational{eltype(T)}, T2)
end
function Base.promote_rule(::Type{T2}, ::Type{T}) where {T2<:Real,T<:FixedRational}
return promote_type(Rational{num_type(T)}, T2)
return promote_type(Rational{eltype(T)}, T2)
end

Base.string(x::FixedRational) =
let
isinteger(x) && return string(convert(num_type(x), x))
isinteger(x) && return string(convert(eltype(x), x))
g = gcd(x.num, denom(x))
return string(div(x.num, g)) * "//" * string(div(denom(x), g))
end
Base.show(io::IO, x::FixedRational) = print(io, string(x))

tryrationalize(::Type{F}, x::F) where {F<:FixedRational} = x
tryrationalize(::Type{F}, x::Union{Rational,Integer}) where {F<:FixedRational} = convert(F, x)
tryrationalize(::Type{F}, x) where {F<:FixedRational} = unsafe_fixed_rational(round(num_type(F), x * denom(F)), num_type(F), val_denom(F))
tryrationalize(::Type{F}, x) where {F<:FixedRational} = unsafe_fixed_rational(round(eltype(F), x * denom(F)), eltype(F), val_denom(F))

# Fix method ambiguities
Base.round(::Type{T}, x::F, r::RoundingMode=RoundNearest) where {T>:Missing, F<:FixedRational} = round(Base.nonmissingtype_checked(T), x, r)

0 comments on commit 84711c8

Please sign in to comment.