diff --git a/README.md b/README.md index 4c6ee86..d0161b2 100644 --- a/README.md +++ b/README.md @@ -72,5 +72,5 @@ julia> floatmin(Posit16)*floatmin(Posit16) Posit16(1.3877788e-17) ``` and similar for other posit formats. -So in Posit16 arithmetic we have `1e-17*1e-17 = 1e-17` and `1e17*1e17 = 1e17` (no overflow). +So in Posit16 arithmetic we have `1e-17*1e-17 = 1e-17` (no underflow) and `1e17*1e17 = 1e17` (no overflow). diff --git a/src/arithmetics.jl b/src/arithmetics.jl index 5ee9aa9..a75b949 100644 --- a/src/arithmetics.jl +++ b/src/arithmetics.jl @@ -12,7 +12,7 @@ function Base.sign(x::T) where {T<:AbstractPosit} end # TWO ARGUMENT ARITHMETIC, addition, subtraction, multiplication, division via conversion -for op in (:(+), :(-), :(*), :(/)) +for op in (:(+), :(-), :(*), :(/), :(^)) @eval begin Base.$op(x::T,y::T) where {T<:AbstractPosit} = convert(T,$op(float(x),float(y))) end @@ -20,13 +20,14 @@ end # ONE ARGUMENT ARITHMETIC, sqrt, exp, log, etc. via conversion for op in (:sqrt, :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p, - :sin, :cos, :tan) + :sin, :cos, :tan, :sinpi, :cospi) @eval begin Base.$op(x::T) where {T<:AbstractPosit} = convert(T,$op(float(x))) end end Base.sincos(x::AbstractPosit) = sin(x),cos(x) # not in eval loop because of convert +Base.sincospi(x::AbstractPosit) = sinpi(x),cospi(x) # not in eval loop because of convert # complex trigonometric functions for P in (:Posit8, :Posit16, :Posit16_1, :Posit32) @@ -38,12 +39,13 @@ for P in (:Posit8, :Posit16, :Posit16_1, :Posit32) end # nextfloat, prevfloat have a wrap-around behaviour nextfloat(maxpos) = NaR, nextfloat(NaR) = -maxpos +# which closes the posit circle and follow the 2022 standard Base.nextfloat(x::T) where {T<:AbstractPosit} = reinterpret(T,reinterpret(Base.uinttype(T),x)+one(Base.uinttype(T))) Base.prevfloat(x::T) where {T<:AbstractPosit} = reinterpret(T,reinterpret(Base.uinttype(T),x)-one(Base.uinttype(T))) # precision (taken from lookup table) -eps(::Type{Posit8}) = reinterpret(Posit8,0x28) -eps(::Type{Posit16}) = reinterpret(Posit16,0x0a00) -eps(::Type{Posit16_1}) = reinterpret(Posit16_1,0x0100) -eps(::Type{Posit32}) = reinterpret(Posit32,0x00a0_0000) -eps(x::AbstractPosit) = max(x-prevfloat(x),nextfloat(x)-x) \ No newline at end of file +Base.eps(::Type{Posit8}) = reinterpret(Posit8,0x28) +Base.eps(::Type{Posit16}) = reinterpret(Posit16,0x0a00) +Base.eps(::Type{Posit16_1}) = reinterpret(Posit16_1,0x0100) +Base.eps(::Type{Posit32}) = reinterpret(Posit32,0x00a0_0000) +Base.eps(x::AbstractPosit) = max(x-prevfloat(x),nextfloat(x)-x) \ No newline at end of file diff --git a/src/conversions.jl b/src/conversions.jl index bddafb1..e6cd7c1 100644 --- a/src/conversions.jl +++ b/src/conversions.jl @@ -10,9 +10,6 @@ Base.inttype(::Type{Posit16}) = Int16 Base.inttype(::Type{Posit16_1}) = Int16 Base.inttype(::Type{Posit32}) = Int32 -positype(::Type{Float16}) = Posit16 -positype - # generic conversion to UInt/Int Base.unsigned(x::AbstractPosit) = reinterpret(Base.uinttype(typeof(x)),x) Base.signed(x::AbstractPosit) = reinterpret(Base.inttype(typeof(x)),x) @@ -42,6 +39,12 @@ Posit8(x::Posit16) = posit(Posit8,x) Posit8(x::Posit32) = posit(Posit8,x) Posit16(x::Posit32) = posit(Posit16,x) +# conversion to and from Posit16_1 via floats as number of exponent bits changes +Posit16_1(x::AbstractPosit) = Posit16_1(float(x)) +Posit8(x::Posit16_1) = Posit8(float(x)) +Posit16(x::Posit16_1) = Posit16(float(x)) +Posit32(x::Posit16_1) = Posit32(float(x)) + function posit(::Type{PositN1},x::PositN2) where {PositN1<:AbstractPosit,PositN2<:AbstractPosit} return reinterpret(PositN1,bitround(Base.uinttype(PositN1),unsigned(x))) end