JeffreySarnoff
11/14/2012 - 7:07 AM

a persistently unsigned 16bit type

a persistently unsigned 16bit type

# unsigned16.jl
#
# A preliminary cut at an always unsigned always 16bits wide type
#
# use : Just require this file, it self imports.
#
# uvalue16 = unsd16(number)
# typeof(uvalue16) == Unsd16
#
# exports: Unsd16, unsd16,
# ~, &, |, $, <<, >>, >>>,
# ==, !=, >=, <, >, <=,
# - , +, *, /, %, ^,
# mod, rem, div, fld,
# iseven, isodd, gcd, gcdx, invmod,
# leading_zeros, leading_ones, trailing_zeros, trailing_ones
#
# author: Jeffrey Sarnoff
# date : 2012-11-14 01:58:00 America/New_York
#
# status: Prerelease: loads & goes for me, untested functions.
#         Suggestions Are Welcome.


module unsigned16

using Base

import Base.~                   ,
       Base.&                   ,
       Base.|                   ,
       Base.$                   ,
       Base.>>                  ,
       Base.<<                  ,
       Base.>>>                 ,
       Base.==                  ,
       Base.!=                  ,
       Base.<=                  ,
       Base.>                   ,
       Base.<                   ,
       Base.>=                  ,
       Base.iseven              ,
       Base.isodd               ,
       Base.-                   ,
       Base.+                   ,
       Base.*                   ,
       Base./                   ,
       Base.%                   ,
       Base.mod                 ,
       Base.rem                 ,
       Base.div                 ,
       Base.fld                 ,
       Base.^                   ,
       Base.gcd                 ,
       Base.gcdx                ,
       Base.invmod              ,
       Base.leading_zeros       ,
       Base.leading_ones        ,
       Base.trailing_zeros      ,
       Base.trailing_ones       ,
       Base.Uint8               ,
       Base.Uint16              ,
       Base.Uint32              ,
       Base.Uint64              ,
       Base.Uint128             ,
       Base.uint8               ,
       Base.uint16              ,
       Base.uint32              ,
       Base.uint64              ,
       Base.uint128             ,
       Base.Int8                ,
       Base.Int16               ,
       Base.Int32               ,
       Base.Int64               ,
       Base.Int128              ,
       Base.convert             ,
       Base.promote_rule


export
       Unsd16, unsd16,
       reinterpret, convert, promote_rule,
       uint8, uint16, uint32, uint64, uint128,
       int8, int16, int32, int64, int128,
       show, print, convert,
       ~, &, |, $, <<, >>, >>>, ==, !=, >=, <, >, <=,
       -, +, *, /, ^, %, mod, rem, div, fld,
       leading_zeros, leading_ones, trailing_zeros, trailing_ones
       # PROBLEM DEFINING AND EXPORTING ===



# partway to genericly NBITS

Uints = Union(Uint8, Uint16, Uint32, Uint64, Uint128)
Sints = Union(Int8, Int16, Int32, Int64, Int128)
SUint = Union(Int32, Int64, Uint32, Uint64)

NBITS = 16

bitstype NBITS Unsd16 <: Unsigned

typealias UnsdT Unsd16
typealias UintT Uint16
typealias SintT  Int16
uintT = uint16
sintT = int16


# double and quadruple bitwidth types for extended intermediate precision
doub_bits(UnsdT) = Uint32
quad_bits(UnsdT) = Uint64
doub_bits(UintT) = Uint32
quad_bits(UintT) = Uint64
doub_bits(SintT) = Int32
quad_bits(SintT) = Int64


# coersions

reinterpret{T<:UnsdT, S<:UintT}(::Type{T}, u::S) = box(T, unbox(S, u))
reinterpret{T<:UnsdT, S<:SintT}(::Type{T}, u::S) = box(T, unbox(S, u))
reinterpret{T<:UintT, S<:UnsdT}(::Type{T}, u::S) = box(T, unbox(S, u))
reinterpret{T<:SintT, S<:UnsdT}(::Type{T}, u::S) = box(T, unbox(S, u))

reinterpret{T<:UnsdT, S<:Uints}(::Type{T}, u::S) =
    box(UnsdT, unbox(UintT, convert(UintT, u)))
reinterpret{T<:UnsdT, S<:Sints}(::Type{T}, s::S) =
    box(UnsdT, unbox(UintT, convert(UintT, convert(Unsigned,s))))

reinterpret{T<:Uints, S<:UnsdT}(::Type{T}, u::S) = convert(T, box(UintT, unbox(UnsdT, u)))
reinterpret{T<:Sints, S<:UnsdT}(::Type{T}, u::S) = convert(T, box(UintT, unbox(UnsdT, u)))

# unsdT( union(Uints,Sints) )


unsd16(u::UintT)  = reinterpret(UnsdT, u)
unsd16(s::SintT)  = reinterpret(UnsdT, s)
unsd16(u::Uints)  = reinterpret(UnsdT, u)
unsd16(s::Sints)  = reinterpret(UnsdT, s)

unsdT = unsd16

uint16(u::UnsdT)  = reinterpret(UintT, u)
 int16(u::UnsdT)  = reinterpret(SintT, u)

uint8  (u::UnsdT) = convert(Uint8  , reinterpret(UintT, u))
uint32 (u::UnsdT) = convert(Uint32 , reinterpret(UintT, u))
uint64 (u::UnsdT) = convert(Uint64 , reinterpret(UintT, u))
uint128(u::UnsdT) = convert(Uint128, reinterpret(UintT, u))

int8  (u::UnsdT) = convert(Int8   , reinterpret(UintT, u))
int32 (u::UnsdT) = convert(Int32  , reinterpret(UintT, u))
int64 (u::UnsdT) = convert(Int64  , reinterpret(UintT, u))
int128(u::UnsdT) = convert(Int128 , reinterpret(UintT, u))


# conversions


convert(::Type{UnsdT}  , u::Uint8)   = reinterpret(UnsdT, uintT(u))
convert(::Type{UnsdT}  , u::Uint16)  = reinterpret(UnsdT, uintT(u))
convert(::Type{UnsdT}  , u::Uint32)  = reinterpret(UnsdT, uintT(u))
convert(::Type{UnsdT}  , u::Uint64)  = reinterpret(UnsdT, uintT(u))
convert(::Type{UnsdT}  , u::Uint128) = reinterpret(UnsdT, uintT(u))

convert(::Type{UnsdT}  , s::Int8)    = reinterpret(UnsdT, uintT(reinterpret(Uint8  , s)))
convert(::Type{UnsdT}  , s::Int16)   = reinterpret(UnsdT, uintT(reinterpret(Uint16 , s)))
convert(::Type{UnsdT}  , s::Int32)   = reinterpret(UnsdT, uintT(reinterpret(Uint32 , s)))
convert(::Type{UnsdT}  , s::Int64)   = reinterpret(UnsdT, uintT(reinterpret(Uint64 , s)))
convert(::Type{UnsdT}  , s::Int128)  = reinterpret(UnsdT, uintT(reinterpret(Uint128, s)))

convert(::Type{Uint8}  , u::UnsdT)   = uint8  (reinterpret(UintT, u))
convert(::Type{Uint16} , u::UnsdT)   = uint16 (reinterpret(UintT, u))
convert(::Type{Uint32} , u::UnsdT)   = uint32 (reinterpret(UintT, u))
convert(::Type{Uint64} , u::UnsdT)   = uint64 (reinterpret(UintT, u))
convert(::Type{Uint128}, u::UnsdT)   = uint128(reinterpret(UintT, u))

convert(::Type{Int8}  , u::UnsdT)   = int8  (reinterpret(UintT, u))
convert(::Type{Int16} , u::UnsdT)   = int16 (reinterpret(UintT, u))
convert(::Type{Int32} , u::UnsdT)   = int32 (reinterpret(UintT, u))
convert(::Type{Int64} , u::UnsdT)   = int64 (reinterpret(UintT, u))
convert(::Type{Int128}, u::UnsdT)   = int128(reinterpret(UintT, u))


# promotions

promote_rule(::Type{UnsdT}, ::Type{Uint8})   = UnsdT
promote_rule(::Type{UnsdT}, ::Type{Uint16 }) = UnsdT # Uint16
promote_rule(::Type{UnsdT}, ::Type{Uint32 }) = UnsdT # Uint32
promote_rule(::Type{UnsdT}, ::Type{Uint64 }) = UnsdT # Uint64
promote_rule(::Type{UnsdT}, ::Type{Uint128}) = UnsdT # Uint128

promote_rule(::Type{UnsdT}, ::Type{Int8})   = UnsdT
promote_rule(::Type{UnsdT}, ::Type{Int16 }) = UnsdT # Int16
promote_rule(::Type{UnsdT}, ::Type{Int32 }) = UnsdT # Int32
promote_rule(::Type{UnsdT}, ::Type{Int64 }) = UnsdT # Int64
promote_rule(::Type{UnsdT}, ::Type{Int128}) = UnsdT # Int128


# leading_[zeros,ones] trailing_[zeros,ones]

leading_zeros (u::UnsdT) = leading_zeros (reinterpret(UintT,u))
leading_ones  (u::UnsdT) = leading_ones  (reinterpret(UintT,u))
trailing_zeros(u::UnsdT) = trailing_zeros(reinterpret(UintT,u))
trailing_ones (u::UnsdT) = trailing_ones (reinterpret(UintT,u))

# show, print

show (io::IO, u::UnsdT) = show (io, reinterpret(UintT,u) )
print(io::IO, u::UnsdT) = print(io, reinterpret(UintT,u) )



# logical operators

(~)(u::UnsdT ) = box(UnsdT,not_int(reinterpret(UintT,u)))
(&)(u::UnsdT, v::UnsdT ) = box(UnsdT,and_int(unbox(UnsdT,u), unbox(UnsdT,v)))
(|)(u::UnsdT, v::UnsdT ) = box(UnsdT,or_int(unbox(UnsdT,u) , unbox(UnsdT,v)))
($)(u::UnsdT, v::UnsdT ) = box(UnsdT,xor_int(unbox(UnsdT,u), unbox(UnsdT,v)))

(<<) (u::UnsdT, v::UnsdT  ) = box(UnsdT,  shl_int(unbox(UnsdT,u), unbox(UnsdT,v)))
(>>) (u::UnsdT, v::UnsdT  ) = box(UnsdT, lshr_int(unbox(UnsdT,u), unbox(UnsdT,v)))
(>>>)(u::UnsdT, v::UnsdT  ) = box(UnsdT, lshr_int(unbox(UnsdT,u), unbox(UnsdT,v)))
(<<) (u::UnsdT, v::UintT  ) = box(UnsdT,  shl_int(unbox(UnsdT,u), unbox(UintT ,v)))
(>>) (u::UnsdT, v::UintT  ) = box(UnsdT, lshr_int(unbox(UnsdT,u), unbox(UintT ,v)))
(>>>)(u::UnsdT, v::UintT  ) = box(UnsdT, lshr_int(unbox(UnsdT,u), unbox(UintT ,v)))
(!=)(u::UnsdT, v::UnsdT) =
  neq_int(unbox(UintT,box(UintT,unbox(UnsdT,u))), unbox(UintT,box(UintT,unbox(UnsdT,v))))
(<)(u::UnsdT, v::UnsdT) =
  ult_int(unbox(UintT,box(UintT,unbox(UnsdT,u))), unbox(UintT,box(UintT,unbox(UnsdT,v))))
(<=)(u::UnsdT, v::UnsdT) =
  ule_int(unbox(UintT,box(UintT,unbox(UnsdT,u))), unbox(UintT,box(UintT,unbox(UnsdT,v))))
(>)(u::UnsdT, v::UnsdT) = !(u <= v)
(>=)(u::UnsdT, v::UnsdT) = !(u < v)

# (===)(u::UnsdT, v::UnsdT) = (===)(box(UintT,unbox(UnsdT,u)),box(UintT,unbox(UnsdT,v)))
#invalid method definition: not a generic function

(iseven)(u::UnsdT ) = iseven(reinterpret(UintT,u))
(isodd)(u::UnsdT )  = isodd(reinterpret(UintT,u))


(-)(u::UnsdT ) = box(UnsdT,neg_int(reinterpret(UintT,u)))

(+)(u::UnsdT, v::UnsdT ) = box(UnsdT,add_int(unbox(UnsdT,u),unbox(UnsdT,v)))
(-)(u::UnsdT, v::UnsdT ) = box(UnsdT,sub_int(unbox(UnsdT,u),unbox(UnsdT,v)))
(*)(u::UnsdT, v::UnsdT ) = box(UnsdT,mul_int(unbox(UnsdT,u),unbox(UnsdT,v)))
(^)(u::UnsdT, v::UnsdT ) = convert(UnsdT, (^)(reinterpret(UintT,u),reinterpret(UintT,v)))
(/)(u::UnsdT, v::UnsdT)  = convert(UnsdT, (div)(reinterpret(UintT,u),reinterpret(UintT,v)))
(%)(u::UnsdT, v::UnsdT)  = convert(UnsdT, (%)(reinterpret(UintT,u),reinterpret(UintT,v)))

(div)(u::UnsdT, v::UnsdT) = convert(UnsdT, (div)(reinterpret(UintT,u),reinterpret(UintT,v)))
(mod)(u::UnsdT, v::UnsdT) = convert(UnsdT, (mod)(reinterpret(UintT,u),reinterpret(UintT,v)))
(rem)(u::UnsdT, v::UnsdT) = convert(UnsdT, (rem)(reinterpret(UintT,u),reinterpret(UintT,v)))
(fld)(u::UnsdT, v::UnsdT) = convert(UnsdT, (fld)(reinterpret(UintT,u),reinterpret(UintT,v)))

(gcd)(u::UnsdT, v::UnsdT) = convert(UnsdT, (gcd)(reinterpret(UintT,u),reinterpret(UintT,v)))
(invmod)(u::UnsdT, v::UnsdT) = convert(UnsdT, (invmod)(reinterpret(UintT,u),reinterpret(UintT,v)))
(gcdx)(u::UnsdT, v::UnsdT) =  map(x->convert(UnsdT,x), (gcdx)(reinterpret(UintT,u),reinterpret(UintT,v)))

end # module



using unsigned16

import unsigned16.Unsd16, unsigned16.unsd16,
       unsigned16.reinterpret, unsigned16.convert, unsigned16.promote_rule,
       unsigned16.uint8, unsigned16.uint16, unsigned16.uint32, unsigned16.uint64, unsigned16.uint128,
       unsigned16.int8, unsigned16.int16, unsigned16.int32, unsigned16.int64, unsigned16.int128,
       unsigned16.show, unsigned16.print,
       unsigned16.~, unsigned16.&, unsigned16.|, unsigned16.$,
       unsigned16.<<, unsigned16.>>, unsigned16.>>>,
       unsigned16.iseven, unsigned16.isodd, unsigned16.gcd, unsigned16.gcdx, unsigned16.invmod,
       unsigned16.-, unsigned16.+, unsigned16.*, unsigned16./, unsigned16.%,
       unsigned16.mod,unsigned16.div, unsigned16.rem, unsigned16.fld,
       unsigned16.leading_zeros, unsigned16.leading_ones,
       unsigned16.trailing_zeros, unsigned16.trailing_ones