diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 0e394c0..e58f26e 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -6,7 +6,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox, zero, oneunit, one, typemin, typemax, floatmin, floatmax, eps, reinterpret, big, rationalize, float, trunc, round, floor, ceil, bswap, clamp, div, fld, cld, rem, mod, mod1, fld1, min, max, minmax, - signed, unsigned, copysign, flipsign, signbit, + signed, unsigned, sign, copysign, flipsign, signbit, length, widen, widemul import Random: Random, AbstractRNG, SamplerType, rand! @@ -370,6 +370,12 @@ clamp(x, ::Type{X}) where {X <: FixedPoint} = clamp(x, typemin(X), typemax(X)) % signed(x::X) where {X <: FixedPoint} = signed(X)(signed(x.i), 0) unsigned(x::X) where {X <: FixedPoint} = unsigned(X)(unsigned(x.i), 0) +function sign(x::X) where {T, X <: FixedPoint{T}} + T <: Unsigned && return iszero(x) ? x : oneunit(X) + # `Q0f7`, etc., result in an error for `oneunit(X)`. + x <= zero(X) && return x === zero(X) ? x : X(-1) + return oneunit(X) +end function copysign(x::X, y::Real) where {T, X <: FixedPoint{T}} T <: Signed ? X(copysign(x.i, y), 0) : throw_not_a_signed_number_error(x) end diff --git a/test/common.jl b/test/common.jl index 2f52ec0..def7f6b 100644 --- a/test/common.jl +++ b/test/common.jl @@ -383,6 +383,12 @@ function test_sign_related(TX::Type) @test_throws Exception unsigned(X) @test_throws Exception unsigned(X(0.5)) + @test sign(X(0.0)) === zero(X) + if typemax(X) >= 1.0 + @test sign(X(0.5)) === oneunit(X) + else + @test_throws ArgumentError sign(X(0.5)) + end @test signbit(X(0.5)) === signbit(X(0.0)) === false end end diff --git a/test/fixed.jl b/test/fixed.jl index baa4c3a..1b5fdd8 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -620,10 +620,7 @@ end @test copysign(0.5Q0f7, -1) === -0.5Q0f7 @test flipsign(0.5Q0f7, 0x1) === 0.5Q0f7 @test flipsign(0.5Q0f7, -1) === -0.5Q0f7 - @test_broken sign(0Q0f7) === zero(Q0f7) - @test_throws ArgumentError sign(0.5Q0f7) - @test sign(0Q1f6) === 0Q1f6 - @test sign(0.5Q1f6) === 1Q1f6 + @test sign(-0.5Q0f7) === -1Q0f7 @test sign(-0.5Q1f6) === -1Q1f6 @test signbit(-0.5Q0f7) === true end diff --git a/test/normed.jl b/test/normed.jl index 8c1010a..28974e3 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -602,8 +602,6 @@ end @test_throws ArgumentError copysign(1N0f8, -1) @test_throws ArgumentError flipsign(1N0f8, 0x1) @test_throws ArgumentError flipsign(1N0f8, -1) - @test_broken sign(0N0f8) === zero(N0f8) - @test_broken sign(0.5N0f8) === oneunit(N0f8) end @testset "bitwise" begin