JeffreySarnoff / SaferIntegers.jl

These integer types use checked arithmetic, otherwise they are as system types.
MIT License
59 stars 10 forks source link

Reorganize type hierarchy such that SafeSigned <: Signed, SafeUnsigned <:Unsigned #20

Closed mkitti closed 3 years ago

mkitti commented 3 years ago

This pull request is my attempt to implement the following:

abstract type SafeUnsigned <: Unsigned end
abstract type SafeSigned <: Signed end
const SafeInteger = Union{SafeUnsigned, SafeSigned}

The unmodified tests currently pass with this and the associated changes.

mkitti commented 3 years ago

we need @inline function $OP(x::T1, y::T2) where {T1<:SafeUnsigned T2<:Unsigned} ...

I think we already have that https://github.com/JeffreySarnoff/SaferIntegers.jl/blob/38dd988d3c1d179af23b56541cfa885a25f35cbd/src/binary_ops.jl#L72

mkitti commented 3 years ago

I'm a bit confused on the changes you requested for promote_rules:

If I replace

promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned   where T<:SafeSigned =
    safeint(promote_type(baseint(S), baseint(T)))
promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned   where T<:SafeUnsigned =
    safeint(promote_type(baseint(S), baseint(T)))
promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:SafeUnsigned =
    safeint(promote_type(baseint(S), baseint(T)))

promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned   where T<:Signed   =
    T <: SafeInteger ? Base.Bottom : S
promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned   where T<:Unsigned =
    T <: SafeInteger ? Base.Bottom : S
promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Signed   =
    T <: SafeInteger ? Base.Bottom : S
promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Unsigned =
    T <: SafeInteger ? Base.Bottom : S

with

promote_rule(::Type{S1}, ::Type{S2}) where {S1<:SafeSigned, S2<:SafeSigned} =
ifelse(sizeof(S1) < sizeof(S2), S2, S1)
promote_rule(::Type{U1}, ::Type{U2}) where {U1<:SafeUnsigned, U2<:SafeUnsigned} =
ifelse(sizeof(U1) < sizeof(U2), U2, U1)
promote_rule(::Type{S}, ::Type{U}) where {S<:SafeSigned, U<:SafeUnsigned} =
ifelse(sizeof(U) < sizeof(S), S, U)

promote_rule(::Type{S}, ::Type{T}) where {S<:SafeSigned, T<:Signed} = S
promote_rule(::Type{S}, ::Type{T}) where {S<:SafeSigned, T<:Unsigned} = S
promote_rule(::Type{S}, ::Type{T}) where {S<:SafeUnsigned, T<:Signed} = S
promote_rule(::Type{S}, ::Type{T}) where {S<:SafeUnsigned, T<:Unsigned} = S

Then I get the following StackOverflow errors upon testing:

checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:385
  Test threw exception
  Expression: SaferIntegers.checked_mul(SafeInt32(7), SafeUInt16(2)) === SafeInt32(7 * 2)
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:386
  Test threw exception
  Expression: SaferIntegers.checked_div(SafeInt32(7), SafeUInt16(2)) === SafeInt32(div(7, 2))
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:387
  Test threw exception
  Expression: SaferIntegers.checked_rem(SafeInt32(7), SafeUInt16(2)) === SafeInt32(rem(7, 2))
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:388
  Test threw exception
  Expression: SaferIntegers.checked_mod(SafeInt32(7), SafeUInt16(2)) === SafeInt32(mod(7, 2))
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:389
  Test threw exception
  Expression: SaferIntegers.checked_fld(SafeInt32(7), SafeUInt16(2)) === SafeInt32(fld(7, 2))
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
checked mixed arithmetic: Error During Test at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:390
  Test threw exception
  Expression: SaferIntegers.checked_cld(SafeInt32(7), SafeUInt16(2)) === SafeInt32(cld(7, 2))
  StackOverflowError:
  Stacktrace:
        [1] promote_type
          @ .\promotion.jl:233 [inlined]
        [2] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{SafeInt32}, #unused#::Type{SafeUInt16})
          @ Base .\promotion.jl:247
  --- the last 2 lines are repeated 79982 more times ---
   [159967] promote_type
          @ .\promotion.jl:233 [inlined]
Test Summary:            | Pass  Error  Total
checked mixed arithmetic |   10      6     16
ERROR: LoadError: Some tests did not pass: 10 passed, 0 failed, 6 errored, 0 broken.
in expression starting at C:\Users\kittisopikulm\.julia\dev\SaferIntegers\test\runtests.jl:373
ERROR: Package SaferIntegers errored during testing
mkitti commented 3 years ago

@inline function $OP(x::T1, y::T2) where {T1<:SafeInteger, T2<:Integer} ...

I added this in https://github.com/JeffreySarnoff/SaferIntegers.jl/pull/20/commits/1080c72a63af86314bfbd8e7b781c19a54bd06d5

JeffreySarnoff commented 3 years ago

I am pleased to know SaferIntegers is in your safe purview. I am merging.

JeffreySarnoff commented 3 years ago

done https://github.com/JeffreySarnoff/SaferIntegers.jl/releases/tag/v3.0.0