@@ -43,6 +43,9 @@ function rawone(::Type{Fixed{T,f}}) where {T, f}
4343 f >= bitwidth (T)- 1 && throw_converterror (Fixed{T,f}, 1 )
4444 oneunit (T) << f
4545end
46+ function rawminusone (:: Type{Fixed{T,f}} ) where {T, f}
47+ (- oneunit (T)) << f
48+ end
4649
4750# unchecked arithmetic
4851
8588(:: Type{TR} )(x:: Fixed{T,f} ) where {TR <: Rational ,T,f} =
8689 TR (x. i>> f + (x. i& (1 << f- 1 ))// (one (widen1 (T))<< f))
8790
91+ # The following are needed for range construction
92+ function round (x:: Fixed{T,f} , :: RoundingMode{:Down} ) where {T,f}
93+ mask = abs (rawminusone (Fixed{T,f}) + oneunit (T))
94+ xraw = reinterpret (x)
95+ return Fixed {T,f} ((xraw & ~ mask) + (signbit (xraw) & (xraw & mask) != 0 ? rawminusone (Fixed{T,f}) : zero (xraw)), 0 )
96+ end
97+ Base. unitrange_last (start:: T , stop:: T ) where {T<: Fixed } =
98+ ifelse (stop >= start, convert (T,start+ floor (stop- start)),
99+ convert (T,start+ T (- 1 )))
100+
101+
102+ # Range lengths
103+ Base. unsafe_length (r:: AbstractUnitRange{X} ) where {X <: Fixed{<:Union{SShorterThanInt,Int},f} } where {f} =
104+ Int (reinterpret (last (r)) >> f - reinterpret (first (r)) >> f) + 1
105+ Base. unsafe_length (r:: AbstractUnitRange{X} ) where {X <: Fixed{T,f} } where {T<: Signed ,f} =
106+ T (reinterpret (last (r)) >> f - reinterpret (first (r)) >> f) + oneunit (T)
107+ Base. length (r:: AbstractUnitRange{X} ) where {X <: Fixed{<:SShorterThanInt,f} } where {f} =
108+ Base. unsafe_length (r)
109+ Base. length (r:: AbstractUnitRange{X} ) where {X <: Fixed{T,f} } where {T<: Signed ,f} =
110+ checked_add (checked_sub (T (reinterpret (last (r)) >> f), T (reinterpret (first (r)) >> f)), oneunit (T))
111+
88112promote_rule (ft:: Type{Fixed{T,f}} , :: Type{TI} ) where {T,f,TI <: Integer } = Fixed{T,f}
89113promote_rule (:: Type{Fixed{T,f}} , :: Type{TF} ) where {T,f,TF <: AbstractFloat } = TF
90114promote_rule (:: Type{Fixed{T,f}} , :: Type{Rational{TR}} ) where {T,f,TR} = Rational{TR}
0 commit comments