Skip to content

Commit

Permalink
Use typed-zero in sign() implementation (#34916)
Browse files Browse the repository at this point in the history
* Use typed-zero in sign() implementation
* Add BigInt and BigFloat specializations
  • Loading branch information
jmert authored Mar 26, 2020
1 parent f4c3f1d commit 458d4bb
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 6 deletions.
7 changes: 6 additions & 1 deletion base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor,
sum, trailing_zeros, trailing_ones, count_ones, tryparse_internal,
bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb,
widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit,
hastypemax
sign, hastypemax

if Clong == Int32
const ClongMax = Union{Int8, Int16, Int32}
Expand Down Expand Up @@ -668,6 +668,11 @@ flipsign!(x::BigInt, y::Integer) = (signbit(y) && (x.size = -x.size); x)
flipsign( x::BigInt, y::Integer) = signbit(y) ? -x : x
flipsign( x::BigInt, y::BigInt) = signbit(y) ? -x : x
# above method to resolving ambiguities with flipsign(::T, ::T) where T<:Signed
function sign(x::BigInt)
isneg(x) && return -one(x)
ispos(x) && return one(x)
return x
end

show(io::IO, x::BigInt) = print(io, string(x))

Expand Down
7 changes: 6 additions & 1 deletion base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import
nextfloat, prevfloat, promote_rule, rem, rem2pi, round, show, float,
sum, sqrt, string, print, trunc, precision, exp10, expm1,
log1p,
eps, signbit, sin, cos, sincos, tan, sec, csc, cot, acos, asin, atan,
eps, signbit, sign, sin, cos, sincos, tan, sec, csc, cot, acos, asin, atan,
cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh,
cbrt, typemax, typemin, unsafe_trunc, floatmin, floatmax, rounding,
setrounding, maxintfloat, widen, significand, frexp, tryparse, iszero,
Expand Down Expand Up @@ -786,6 +786,11 @@ cmp(x::CdoubleMax, y::BigFloat) = -cmp(y,x)
<=(x::CdoubleMax, y::BigFloat) = !isnan(x) && !isnan(y) && cmp(y,x) >= 0

signbit(x::BigFloat) = ccall((:mpfr_signbit, :libmpfr), Int32, (Ref{BigFloat},), x) != 0
function sign(x::BigFloat)
c = cmp(x, 0)
(c == 0 || isnan(x)) && return x
return c < 0 ? -one(x) : one(x)
end

function precision(x::BigFloat) # precision of an object of type BigFloat
return ccall((:mpfr_get_prec, :libmpfr), Clong, (Ref{BigFloat},), x)
Expand Down
6 changes: 3 additions & 3 deletions base/number.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ signbit(x::Real) = x < 0
Return zero if `x==0` and ``x/|x|`` otherwise (i.e., ±1 for real `x`).
"""
sign(x::Number) = x == 0 ? x/abs(oneunit(x)) : x/abs(x)
sign(x::Real) = ifelse(x < 0, oftype(one(x),-1), ifelse(x > 0, one(x), typeof(one(x))(x)))
sign(x::Unsigned) = ifelse(x > 0, one(x), oftype(one(x),0))
sign(x::Number) = iszero(x) ? x/abs(oneunit(x)) : x/abs(x)
sign(x::Real) = ifelse(x < zero(x), oftype(one(x),-1), ifelse(x > zero(x), one(x), typeof(one(x))(x)))
sign(x::Unsigned) = ifelse(x > zero(x), one(x), oftype(one(x),0))
abs(x::Real) = ifelse(signbit(x), -x, x)

"""
Expand Down
10 changes: 10 additions & 0 deletions test/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ end
@test rem(BigInt(i), BigInt(j)) == rem(i,j)
end
end
@testset "copysign / sign" begin
x = BigInt(1)
y = BigInt(-1)
@test copysign(x, y) == y
@test copysign(y, x) == x

@test sign(BigInt(-3)) == -1
@test sign(BigInt( 0)) == 0
@test sign(BigInt( 3)) == 1
end

@testset "Signed addition" begin
@test a+Int8(1) == b
Expand Down
8 changes: 7 additions & 1 deletion test/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,18 @@ end
end
end

@testset "copysign" begin
@testset "copysign / sign" begin
x = BigFloat(1)
y = BigFloat(-1)
@test copysign(x, y) == y
@test copysign(y, x) == x
@test copysign(1.0, BigFloat(NaN)) == 1.0

@test sign(BigFloat(-3.0)) == -1.0
@test sign(BigFloat( 3.0)) == 1.0
@test isequal(sign(BigFloat(-0.0)), BigFloat(-0.0))
@test isequal(sign(BigFloat( 0.0)), BigFloat( 0.0))
@test isnan(sign(BigFloat(NaN)))
end
@testset "isfinite / isinf / isnan" begin
x = BigFloat(Inf)
Expand Down
6 changes: 6 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,12 @@ end
@test sign(one(UInt)) == 1
@test sign(zero(UInt)) == 0

isdefined(Main, :Furlongs) || @eval Main include("testhelpers/Furlongs.jl")
using .Main.Furlongs
x = Furlong(3.0)
@test sign(x) * x == x
@test sign(-x) * -x == x

@test signbit(1) == 0
@test signbit(0) == 0
@test signbit(-1) == 1
Expand Down

2 comments on commit 458d4bb

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily package evaluation, I will reply here when finished:

@nanosoldier runtests(ALL, isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your package evaluation job has completed - possible new issues were detected. A full report can be found here. cc @maleadt

Please sign in to comment.