Created
January 15, 2020 11:57
-
-
Save timholy/569475b24763d1fbd36a42634192cb74 to your computer and use it in GitHub Desktop.
Prototype of NaNIntegers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module NaNIntegers | |
import Base: <, <=, +, -, *, ~, &, |, <<, >>, >>>, xor | |
export NInt16, NInt32, NInt64, NInt128, NInt | |
export NaNI16, NaNI32, NaNI64, NaNI128 | |
abstract type NSigned <: Signed end | |
primitive type NInt16 <: NSigned 16 end | |
primitive type NInt32 <: NSigned 32 end | |
primitive type NInt64 <: NSigned 64 end | |
primitive type NInt128 <: NSigned 128 end | |
if Sys.WORD_SIZE == 32 | |
const NInt = NInt32 | |
else | |
const NInt = NInt64 | |
end | |
## Traits | |
itype(::Type{NSigned}) = Signed | |
itype(::Type{NInt16}) = Int16 | |
itype(::Type{NInt32}) = Int32 | |
itype(::Type{NInt64}) = Int64 | |
itype(::Type{NInt128}) = Int128 | |
itype(x::NSigned) = itype(typeof(x)) | |
ntype(::Type{Signed}) = NSigned | |
ntype(::Type{Int16}) = NInt16 | |
ntype(::Type{Int32}) = NInt32 | |
ntype(::Type{Int64}) = NInt64 | |
ntype(::Type{Int128}) = NInt128 | |
ntype(x::Signed) = rtype(typeof(x)) | |
nanmask(::Type{NInt16}) = 0x4000 | |
nanmask(::Type{NInt32}) = 0x40000000 | |
nanmask(::Type{NInt64}) = 0x4000000000000000 | |
nanmask(::Type{NInt128}) = 0x40000000000000000000000000000000 | |
nanmask(::Type{S}) where S<:Signed = nanmask(ntype(S)) | |
nanmask(x::Integer) = nanmask(typeof(x)) | |
## Constructors | |
checknan(x) = (x & nanmask(x)) == zero(nanmask(x)) || throw(DomainError(x, "NaN bit must not be set")) | |
NInt16(x::Int16) = (checknan(x); reinterpret(NInt16, x)) | |
NInt32(x::Int32) = (checknan(x); reinterpret(NInt32, x)) | |
NInt64(x::Int64) = (checknan(x); reinterpret(NInt64, x)) | |
NInt128(x::Int128) = (checknan(x); reinterpret(NInt128, x)) | |
(::Type{N})(x) where N<:NSigned = N(convert(itype(N), x)) | |
Base.rem(x::Int16, ::Type{NInt16}) = reinterpret(NInt16, x) | |
Base.rem(x::Int32, ::Type{NInt32}) = reinterpret(NInt32, x) | |
Base.rem(x::Int64, ::Type{NInt64}) = reinterpret(NInt64, x) | |
Base.rem(x::Int128, ::Type{NInt128}) = reinterpret(NInt128, x) | |
const NaNI16 = Int16(nanmask(NInt16)) % NInt16 | |
const NaNI32 = Int32(nanmask(NInt32)) % NInt32 | |
const NaNI64 = Int64(nanmask(NInt64)) % NInt64 | |
const NaNI128 = Int128(nanmask(NInt128)) % NInt128 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment