Skip to content

Commit

Permalink
Merge pull request JuliaLang#14535 from eschnett/eschnett/bit-int-types
Browse files Browse the repository at this point in the history
Rename internal `int.jl` type tuples and unions for clarity
  • Loading branch information
vtjnash committed Jan 25, 2016
2 parents 66fb858 + 2665574 commit f11d389
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 70 deletions.
2 changes: 1 addition & 1 deletion base/hashing2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ end

## streamlined hashing for smallish rational types ##

function hash{T<:Integer64}(x::Rational{T}, h::UInt)
function hash{T<:BitInteger64}(x::Rational{T}, h::UInt)
num, den = Base.num(x), Base.den(x)
den == 1 && return hash(num, h)
den == 0 && return hash(ifelse(num > 0, Inf, -Inf), h)
Expand Down
89 changes: 43 additions & 46 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,26 @@

## integer arithmetic ##

# The tuples and types that do not include 128 bit sizes are necessary to handle certain
# issues on 32-bit machines, and also to simplify promotion rules, as they are also used
# elsewhere where Int128/UInt128 support is separated out, such as in hashing2.jl

const Signed64Types = (Int8,Int16,Int32,Int64)
const Unsigned64Types = (UInt8,UInt16,UInt32,UInt64)
const IntTypes = tuple(Signed64Types..., Int128, Unsigned64Types..., UInt128)

typealias UnionIntTypes Union{IntTypes...}
typealias UnionS64Types Union{Signed64Types...}
typealias UnionU64Types Union{Unsigned64Types...}
typealias Integer64 Union{Signed64Types..., Unsigned64Types...}
typealias SignedIntTypes Union{Signed64Types..., Int128}
typealias UnsignedIntTypes Union{Unsigned64Types..., UInt128}
# The tuples and types that do not include 128 bit sizes are necessary to handle
# certain issues on 32-bit machines, and also to simplify promotion rules, as
# they are also used elsewhere where Int128/UInt128 support is separated out,
# such as in hashing2.jl

typealias BitSigned64 Union{Int8,Int16,Int32,Int64}
typealias BitUnsigned64 Union{UInt8,UInt16,UInt32,UInt64}
typealias BitInteger64 Union{BitSigned64,BitUnsigned64}
typealias BitSigned Union{BitSigned64,Int128}
typealias BitUnsigned Union{BitUnsigned64,UInt128}
typealias BitInteger Union{BitSigned,BitUnsigned}

## integer comparisons ##

<{T<:SignedIntTypes}(x::T, y::T) = slt_int(unbox(T,x),unbox(T,y))
<{T<:BitSigned}(x::T, y::T) = slt_int(unbox(T,x),unbox(T,y))

-{T<:UnionIntTypes}(x::T) = box(T, neg_int(unbox(T,x)))
-{T<:UnionIntTypes}(x::T, y::T) = box(T, sub_int(unbox(T,x),unbox(T,y)))
+{T<:UnionIntTypes}(x::T, y::T) = box(T, add_int(unbox(T,x),unbox(T,y)))
*{T<:UnionIntTypes}(x::T, y::T) = box(T, mul_int(unbox(T,x),unbox(T,y)))
-{T<:BitInteger}(x::T) = box(T, neg_int(unbox(T,x)))
-{T<:BitInteger}(x::T, y::T) = box(T, sub_int(unbox(T,x),unbox(T,y)))
+{T<:BitInteger}(x::T, y::T) = box(T, add_int(unbox(T,x),unbox(T,y)))
*{T<:BitInteger}(x::T, y::T) = box(T, mul_int(unbox(T,x),unbox(T,y)))

/(x::Integer, y::Integer) = float(x)/float(y)
inv(x::Integer) = float(one(x))/float(x)
Expand All @@ -35,7 +32,7 @@ iseven(n::Integer) = !isodd(n)
signbit(x::Integer) = x < 0
signbit(x::Unsigned) = false

flipsign{T<:SignedIntTypes}(x::T, y::T) = box(T,flipsign_int(unbox(T,x),unbox(T,y)))
flipsign{T<:BitSigned}(x::T, y::T) = box(T,flipsign_int(unbox(T,x),unbox(T,y)))

flipsign(x::Signed, y::Signed) = convert(typeof(x), flipsign(promote(x,y)...))
flipsign(x::Signed, y::Float16) = flipsign(x, reinterpret(Int16,y))
Expand Down Expand Up @@ -90,10 +87,10 @@ cld(x::Unsigned, y::Signed) = div(x,y)+(!signbit(y)&(rem(x,y)!=0))

# Don't promote integers for div/rem/mod since there is no danger of overflow,
# while there is a substantial performance penalty to 64-bit promotion.
div{T<:UnionS64Types}(x::T, y::T) = box(T,checked_sdiv_int(unbox(T,x),unbox(T,y)))
rem{T<:UnionS64Types}(x::T, y::T) = box(T,checked_srem_int(unbox(T,x),unbox(T,y)))
div{T<:UnionU64Types}(x::T, y::T) = box(T,checked_udiv_int(unbox(T,x),unbox(T,y)))
rem{T<:UnionU64Types}(x::T, y::T) = box(T,checked_urem_int(unbox(T,x),unbox(T,y)))
div{T<:BitSigned64}(x::T, y::T) = box(T,checked_sdiv_int(unbox(T,x),unbox(T,y)))
rem{T<:BitSigned64}(x::T, y::T) = box(T,checked_srem_int(unbox(T,x),unbox(T,y)))
div{T<:BitUnsigned64}(x::T, y::T) = box(T,checked_udiv_int(unbox(T,x),unbox(T,y)))
rem{T<:BitUnsigned64}(x::T, y::T) = box(T,checked_urem_int(unbox(T,x),unbox(T,y)))

# x == fld(x,y)*y + mod(x,y)
mod{T<:Unsigned}(x::T, y::T) = rem(x,y)
Expand Down Expand Up @@ -121,33 +118,33 @@ end

## integer bitwise operations ##

(~){T<:UnionIntTypes}(x::T) = box(T,not_int(unbox(T,x)))
(&){T<:UnionIntTypes}(x::T, y::T) = box(T,and_int(unbox(T,x),unbox(T,y)))
(|){T<:UnionIntTypes}(x::T, y::T) = box(T, or_int(unbox(T,x),unbox(T,y)))
($){T<:UnionIntTypes}(x::T, y::T) = box(T,xor_int(unbox(T,x),unbox(T,y)))
(~){T<:BitInteger}(x::T) = box(T,not_int(unbox(T,x)))
(&){T<:BitInteger}(x::T, y::T) = box(T,and_int(unbox(T,x),unbox(T,y)))
(|){T<:BitInteger}(x::T, y::T) = box(T, or_int(unbox(T,x),unbox(T,y)))
($){T<:BitInteger}(x::T, y::T) = box(T,xor_int(unbox(T,x),unbox(T,y)))

>>{T<:SignedIntTypes,S<:Integer64}(x::T, y::S) = box(T,ashr_int(unbox(T,x),unbox(S,y)))
>>{T<:UnsignedIntTypes,S<:Integer64}(x::T, y::S) = box(T,lshr_int(unbox(T,x),unbox(S,y)))
<<{T<:UnionIntTypes,S<:Integer64}(x::T, y::S) = box(T, shl_int(unbox(T,x),unbox(S,y)))
>>>{T<:UnionIntTypes,S<:Integer64}(x::T, y::S) = box(T,lshr_int(unbox(T,x),unbox(S,y)))
>>{T<:BitSigned,S<:BitInteger64}(x::T, y::S) = box(T,ashr_int(unbox(T,x),unbox(S,y)))
>>{T<:BitUnsigned,S<:BitInteger64}(x::T, y::S) = box(T,lshr_int(unbox(T,x),unbox(S,y)))
<<{T<:BitInteger,S<:BitInteger64}(x::T, y::S) = box(T, shl_int(unbox(T,x),unbox(S,y)))
>>>{T<:BitInteger,S<:BitInteger64}(x::T, y::S) = box(T,lshr_int(unbox(T,x),unbox(S,y)))

bswap{T<:Union{Int8,UInt8}}(x::T) = x
bswap{T<:Union{Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128}}(x::T) =
box(T,bswap_int(unbox(T,x)))

count_ones{T<:UnionIntTypes}(x::T) = Int(box(T,ctpop_int(unbox(T,x))))
leading_zeros{T<:UnionIntTypes}(x::T) = Int(box(T,ctlz_int(unbox(T,x))))
trailing_zeros{T<:UnionIntTypes}(x::T) = Int(box(T,cttz_int(unbox(T,x))))
count_ones{T<:BitInteger}(x::T) = Int(box(T,ctpop_int(unbox(T,x))))
leading_zeros{T<:BitInteger}(x::T) = Int(box(T,ctlz_int(unbox(T,x))))
trailing_zeros{T<:BitInteger}(x::T) = Int(box(T,cttz_int(unbox(T,x))))

count_zeros( x::Integer) = count_ones(~x)
leading_ones( x::Integer) = leading_zeros(~x)
trailing_ones(x::Integer) = trailing_zeros(~x)

## integer comparisons ##

<{T<:UnsignedIntTypes}(x::T, y::T) = ult_int(unbox(T,x),unbox(T,y))
<={T<:SignedIntTypes}(x::T, y::T) = sle_int(unbox(T,x),unbox(T,y))
<={T<:UnsignedIntTypes}(x::T, y::T) = ule_int(unbox(T,x),unbox(T,y))
<{T<:BitUnsigned}(x::T, y::T) = ult_int(unbox(T,x),unbox(T,y))
<={T<:BitSigned}(x::T, y::T) = sle_int(unbox(T,x),unbox(T,y))
<={T<:BitUnsigned}(x::T, y::T) = ule_int(unbox(T,x),unbox(T,y))

==(x::Signed, y::Unsigned) = (x >= 0) & (unsigned(x) == y)
==(x::Unsigned, y::Signed ) = (y >= 0) & (x == unsigned(y))
Expand All @@ -158,7 +155,7 @@ trailing_ones(x::Integer) = trailing_zeros(~x)

## integer conversions ##

for to in IntTypes, from in tuple(IntTypes...,Bool)
for to in tuple(BitInteger.types...), from in tuple(BitInteger.types...,Bool)
if !(to === from)
if to.size < from.size
if issubtype(to, Signed)
Expand Down Expand Up @@ -204,9 +201,9 @@ rem{T<:Integer}(x::T, ::Type{T}) = x
rem(x::Integer, ::Type{Bool}) = ((x&1)!=0)
mod{T<:Integer}(x::Integer, ::Type{T}) = rem(x, T)

convert{T<:UnionS64Types,Tf<:Union{Float32,Float64}}(::Type{T}, x::Tf) =
convert{T<:BitSigned64,Tf<:Union{Float32,Float64}}(::Type{T}, x::Tf) =
box(T,checked_fptosi(T,unbox(Tf,x)))
convert{T<:UnionU64Types,Tf<:Union{Float32,Float64}}(::Type{T}, x::Tf) =
convert{T<:BitUnsigned64,Tf<:Union{Float32,Float64}}(::Type{T}, x::Tf) =
box(T,checked_fptoui(T,unbox(Tf,x)))

convert{T<:Union{Int128,UInt128},Tf<:Union{Float32,Float64}}(::Type{T},x::Tf) =
Expand Down Expand Up @@ -264,18 +261,18 @@ promote_rule{T<:Union{Int8,Int16}}(::Type{Int32}, ::Type{T}) = Int32
promote_rule{T<:Union{UInt8,UInt16}}(::Type{UInt32}, ::Type{T}) = UInt32
promote_rule{T<:Union{Int8,Int16,Int32}}(::Type{Int64}, ::Type{T}) = Int64
promote_rule{T<:Union{UInt8,UInt16,UInt32}}(::Type{UInt64}, ::Type{T}) = UInt64
promote_rule{T<:UnionS64Types}(::Type{Int128}, ::Type{T}) = Int128
promote_rule{T<:UnionU64Types}(::Type{UInt128}, ::Type{T}) = UInt128
for T in tuple(Signed64Types...,Int128)
promote_rule{T<:BitSigned64}(::Type{Int128}, ::Type{T}) = Int128
promote_rule{T<:BitUnsigned64}(::Type{UInt128}, ::Type{T}) = UInt128
for T in tuple(BitSigned.types...)
@eval promote_rule{S<:Union{UInt8,UInt16}}(::Type{S}, ::Type{$T}) =
$(sizeof(T) < sizeof(Int) ? Int : T)
end
@eval promote_rule{T<:Union{Int8,Int16,Int32}}(::Type{UInt32}, ::Type{T}) =
$(WORD_SIZE == 64 ? Int : UInt)
promote_rule(::Type{UInt32}, ::Type{Int64}) = Int64
promote_rule{T<:UnionS64Types}(::Type{UInt64}, ::Type{T}) = UInt64
promote_rule{T<:BitSigned64}(::Type{UInt64}, ::Type{T}) = UInt64
promote_rule{T<:Union{UInt32, UInt64}}(::Type{T}, ::Type{Int128}) = Int128
promote_rule{T<:SignedIntTypes}(::Type{UInt128}, ::Type{T}) = UInt128
promote_rule{T<:BitSigned}(::Type{UInt128}, ::Type{T}) = UInt128

promote_op{R<:Integer,S<:Integer}(op, ::Type{R}, ::Type{S}) = typeof(op(one(R), one(S)))

Expand Down
2 changes: 1 addition & 1 deletion base/printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export @printf, @sprintf

### printf formatter generation ###
const SmallFloatingPoint = Union{Float64,Float32,Float16}
const SmallNumber = Union{SmallFloatingPoint,Base.Integer64,UInt128,Int128}
const SmallNumber = Union{SmallFloatingPoint,Base.BitInteger}

function gen(s::AbstractString)
args = []
Expand Down
8 changes: 4 additions & 4 deletions base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type Close1Open2 <: FloatInterval end
RandomDevice(unlimited::Bool=true) = new(open(unlimited ? "/dev/urandom" : "/dev/random"))
end

rand{ T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice, ::Type{T}) = read( rd.file, T)
rand!{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice, A::Array{T}) = read!(rd.file, A)
rand{ T<:Union{Bool, Base.BitInteger}}(rd::RandomDevice, ::Type{T}) = read( rd.file, T)
rand!{T<:Union{Bool, Base.BitInteger}}(rd::RandomDevice, A::Array{T}) = read!(rd.file, A)
end

@windows_only begin
Expand All @@ -47,12 +47,12 @@ end
RandomDevice() = new(Array(UInt128, 1))
end

function rand{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice, ::Type{T})
function rand{T<:Union{Bool, Base.BitInteger}}(rd::RandomDevice, ::Type{T})
win32_SystemFunction036!(rd.buffer)
@inbounds return rd.buffer[1] % T
end

rand!{T<:Union{Bool, Base.IntTypes...}}(rd::RandomDevice, A::Array{T}) = (win32_SystemFunction036!(A); A)
rand!{T<:Union{Bool, Base.BitInteger}}(rd::RandomDevice, A::Array{T}) = (win32_SystemFunction036!(A); A)
end

rand(rng::RandomDevice, ::Type{Close1Open2}) =
Expand Down
18 changes: 8 additions & 10 deletions test/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ for y in (4, Float32(4), 4.0, big(4.0))
end

# Result type must be type of first argument
for T in (Int8,Int16,Int32,Int64,Int128,BigInt,
UInt8,UInt16,UInt32,UInt64,UInt128,
Rational{Int},Rational{BigInt},
Float16,Float32,Float64)
for U in (Int8,Int16,Int32,Int64,Int128,BigInt,
Rational{Int},Rational{BigInt},
UInt8,UInt16,UInt32,UInt64,UInt128,
Float16,Float32,Float64)
for T in (Base.BitInteger.types..., BigInt,
Rational{Int}, Rational{BigInt},
Float16, Float32, Float64)
for U in (Base.BitInteger.types..., BigInt,
Rational{Int}, Rational{BigInt},
Float16, Float32, Float64)
@test typeof(copysign(T(3), U(4))) === T
@test typeof(flipsign(T(3), U(4))) === T
end
Expand Down Expand Up @@ -91,8 +89,8 @@ end
bitstype 8 MyBitsType <: Integer
@test_throws MethodError ~reinterpret(MyBitsType, 0x7b)

UItypes = (UInt8, UInt16, UInt32, UInt64, UInt128)
SItypes = (Int8, Int16, Int32, Int64, Int128)
UItypes = Base.BitUnsigned.types
SItypes = Base.BitSigned.types

for T in UItypes, S in UItypes
@test promote(S(3), T(3)) === (sizeof(T) < sizeof(S) ? (S(3), S(3)) : (T(3), T(3)))
Expand Down
14 changes: 7 additions & 7 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ end
@test_approx_eq (Complex(1,2)/Complex(2.5,3.0))*Complex(2.5,3.0) Complex(1,2)
@test 0.7 < real(sqrt(Complex(0,1))) < 0.707107

for T in [Int8, Int16, Int32, Int64, Int128]
for T in Base.BitSigned.types
@test abs(typemin(T)) == -typemin(T)
#for x in (typemin(T),convert(T,-1),zero(T),one(T),typemax(T))
# @test signed(unsigned(x)) == x
Expand All @@ -1137,16 +1137,16 @@ end
# @test unsigned(signed(x)) == x
#end

for S = [Int8, Int16, Int32, Int64],
U = [UInt8, UInt16, UInt32, UInt64]
for S = Base.BitSigned64.types,
U = Base.BitUnsigned64.types
@test !(-one(S) == typemax(U))
@test -one(S) != typemax(U)
@test -one(S) < typemax(U)
@test !(typemax(U) <= -one(S))
end

# check type of constructed rationals
int_types = [Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64]
int_types = Base.BitInteger64.types
for N = int_types, D = int_types
T = promote_type(N,D)
@test typeof(convert(N,2)//convert(D,3)) <: Rational{T}
Expand All @@ -1156,9 +1156,9 @@ end
@test typeof(convert(Rational{Integer},1)) === Rational{Integer}

# check type of constructed complexes
real_types = [Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float32, Float64,
Rational{Int8}, Rational{UInt8}, Rational{Int16}, Rational{UInt16},
Rational{Int32}, Rational{UInt32}, Rational{Int64}, Rational{UInt64}]
real_types = [Base.BitInteger64.types...,
[Rational{T} for T in Base.BitInteger64.types]...,
Float32, Float64]
for A = real_types, B = real_types
T = promote_type(A,B)
@test typeof(Complex(convert(A,2),convert(B,3))) <: Complex{T}
Expand Down
2 changes: 1 addition & 1 deletion test/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ for rng in ([], [MersenneTwister()], [RandomDevice()])
rand!(rng..., BitArray(5)) ::BitArray{1}
rand!(rng..., BitArray(2, 3)) ::BitArray{2}

for T in [Base.IntTypes..., Bool, Char, Float16, Float32, Float64]
for T in [Base.BitInteger.types..., Bool, Char, Float16, Float32, Float64]
a0 = rand(rng..., T) ::T
a1 = rand(rng..., T, 5) ::Vector{T}
a2 = rand(rng..., T, 2, 3) ::Array{T, 2}
Expand Down

0 comments on commit f11d389

Please sign in to comment.