@@ -6,6 +6,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
66 zero, oneunit, one, typemin, typemax, floatmin, floatmax, eps, reinterpret,
77 big, rationalize, float, trunc, round, floor, ceil, bswap, clamp,
88 div, fld, rem, mod, mod1, fld1, min, max, minmax,
9+ signed, unsigned, copysign, flipsign, signbit,
910 rand, length
1011
1112import Statistics # for _mean_promote
@@ -46,6 +47,9 @@ reinterpret(::Type{X}, x::T) where {T <: Integer, X <: FixedPoint{T}} = X(x, 0)
4647nbitsfrac (:: Type{X} ) where {T, f, X <: FixedPoint{T,f} } = f
4748rawtype (:: Type{X} ) where {T, X <: FixedPoint{T} } = T
4849
50+ # traits based on static parameters
51+ signbits (:: Type{X} ) where {T, X <: FixedPoint{T} } = T <: Unsigned ? 0 : 1
52+
4953# construction using the (approximate) intended value, i.e., N0f8
5054* (x:: Real , :: Type{X} ) where {X <: FixedPoint } = _convert (X, x)
5155
@@ -189,6 +193,30 @@ clamp(x::X, lo::X, hi::X) where {X <: FixedPoint} = X(clamp(x.i, lo.i, hi.i), 0)
189193
190194clamp (x, :: Type{X} ) where {X <: FixedPoint } = clamp (x, typemin (X), typemax (X)) % X
191195
196+ # Since `FixedPoint` is not an integer type, it is not clear in what type
197+ # `signed` and `unsigned` for `FixedPoint` should return values. They should
198+ # currently throw errors in case we support "unsigned Fixed" or "signed Normed"
199+ # in the future. The following "incomplete" code is necessary for Julia v1.0
200+ # etc. to prevent accidental conversion to an integer type.
201+ signed (x:: X ) where {X <: FixedPoint } = signed (X)(signed (x. i), 0 )
202+ unsigned (x:: X ) where {X <: FixedPoint } = unsigned (X)(unsigned (x. i), 0 )
203+
204+ function copysign (x:: X , y:: Real ) where {T, X <: FixedPoint{T} }
205+ T <: Signed ? X (copysign (x. i, y), 0 ) : throw_not_a_signed_number_error (x)
206+ end
207+ function flipsign (x:: X , y:: Real ) where {T, X <: FixedPoint{T} }
208+ T <: Signed ? X (flipsign (x. i, y), 0 ) : throw_not_a_signed_number_error (x)
209+ end
210+ if copysign (- 1 , 0x1 ) != = 1 # for Julia v1.0 and v1.1 (julia #30748)
211+ copysign (x:: X , y:: Unsigned ) where {T, X <: FixedPoint{T} } = copysign (x, signed (y))
212+ flipsign (x:: X , y:: Unsigned ) where {T, X <: FixedPoint{T} } = flipsign (x, signed (y))
213+ end
214+ @noinline function throw_not_a_signed_number_error (x)
215+ throw (ArgumentError (" $x is not a signed number." ))
216+ end
217+
218+ signbit (x:: X ) where {X <: FixedPoint } = signbit (x. i)
219+
192220for f in (:zero , :oneunit , :one , :eps , :rawone , :rawtype , :floattype )
193221 @eval begin
194222 $ f (x:: FixedPoint ) = $ f (typeof (x))
0 commit comments