JeffreySarnoff / SaferIntegers.jl

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

Ambiguous constructors #11

Closed sostock closed 5 years ago

sostock commented 5 years ago

Some of the constructors defined in this package lead to method ambiguities:

julia> using SaferIntegers

julia> UInt128(BigInt(2))
ERROR: MethodError: UInt128(::BigInt) is ambiguous. Candidates:
  (::Type{T})(x::BigInt) where T<:Union{UInt128, UInt16, UInt32, UInt64, UInt8} in Base.GMP at gmp.jl:321
  UInt128(x::T) where T<:Signed in SaferIntegers at ~/.julia/packages/SaferIntegers/iaRR8/src/construct.jl:83
Possible fix, define
  UInt128(::BigInt)

This can probably be solved by deleting the following four lines, which define constructors that should already exist in Base: https://github.com/JeffreySarnoff/SaferIntegers.jl/blob/3cab3bfd1967ff52cfcbe76e6143d9e5377ebe50/src/construct.jl#L80-L83

JeffreySarnoff commented 5 years ago

thanks again. looking into it.

JeffreySarnoff commented 5 years ago

Fixed on master (your guidance was helpful), added tests. Registration of v2.2.1 pending. Thanks again.

JeffreySarnoff commented 5 years ago

@sostock What is your opinion on trapping shifts beyond the bitwidth of the shifted type? Originally, I ignored them because the result is 0 at or after the bitwidth of the shifted type. Later on, I changed this to trap shifts greater than the bitwidth of the shifted type because that should not be done in some strict sense. There is a possible use case, where the amount shifted is the result of some other computation where values greater than the bitwidth of the shifted type are left untrimmed for speed -- but that could be from carelessness.

sostock commented 5 years ago

@JeffreySarnoff Regarding the bit-shift question, I don’t have any strong opinions either way, but I don’t think the trapping is necessary. I think that people who use bit-shift operators would know their behavior and might even expect it to be the same as for the “unsafe” integer types. On the other hand, the trapping doesn’t hurt since it prints a pretty clear error message and the behavior can be repaired by just clamping the value.

Is there any precedent for the trapping, i.e., any language that disallows bit-shifts by more than 8*sizeof(T) or any standard that regards such bit-shifts as invalid/undefined?

JeffreySarnoff commented 5 years ago

If the value of the right operand is negative or greater than or equal to the width of the promoted left operand, the behavior is undefined. C11 §6.5.7 3

and http://c0x.coding-guidelines.com/6.5.7.html

1185 If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

I don't trap x >> -n unless abs(n) > sizeof(x)*8, because Julia allows negative shifts (they go the other way).

JeffreySarnoff commented 5 years ago

Having found those .. I'm keeping it as is. Thank you for the feedback.