@@ -6,6 +6,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
66 zero, oneunit, one, typemin, typemax, floatmin, floatmax, eps, sizeof, reinterpret,
77 float, trunc, round, floor, ceil, bswap,
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
173174
174175bswap (x:: X ) where {X <: FixedPoint } = sizeof (X) == 1 ? x : X (bswap (x. i), 0 )
175176
177+ # Since `FixedPoint` is not an integer type, it is not clear in what type
178+ # `signed` and `unsigned` for `FixedPoint` should return values. They should
179+ # currently throw errors in case we support "unsigned Fixed" or "signed Normed"
180+ # in the future. The following "incomplete" code is necessary for Julia v1.0
181+ # etc. to prevent accidental conversion to an integer type.
182+ signed (x:: X ) where {X <: FixedPoint } = signed (X)(signed (x. i), 0 )
183+ unsigned (x:: X ) where {X <: FixedPoint } = unsigned (X)(unsigned (x. i), 0 )
184+
185+ function copysign (x:: X , y:: Real ) where {T, X <: FixedPoint{T} }
186+ T <: Signed ? X (copysign (x. i, y), 0 ) : throw_not_a_signed_number_error (x)
187+ end
188+ function flipsign (x:: X , y:: Real ) where {T, X <: FixedPoint{T} }
189+ T <: Signed ? X (flipsign (x. i, y), 0 ) : throw_not_a_signed_number_error (x)
190+ end
191+ if copysign (- 1 , 0x1 ) != = 1 # for Julia v1.0 and v1.1 (julia #30748)
192+ copysign (x:: X , y:: Unsigned ) where {T, X <: FixedPoint{T} } = copysign (x, signed (y))
193+ flipsign (x:: X , y:: Unsigned ) where {T, X <: FixedPoint{T} } = flipsign (x, signed (y))
194+ end
195+ @noinline function throw_not_a_signed_number_error (x)
196+ throw (ArgumentError (" $x is not a signed number." ))
197+ end
198+
199+ signbit (x:: X ) where {X <: FixedPoint } = signbit (x. i)
200+
176201for f in (:zero , :oneunit , :one , :eps , :rawone , :rawtype , :floattype )
177202 @eval begin
178203 $ f (x:: FixedPoint ) = $ f (typeof (x))
0 commit comments