Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Base.max behavior for UInt64 & UInt128 (InexactError) vs UInt8/Uint16/Uint32 #48971

Closed
robertfeldt opened this issue Mar 11, 2023 · 2 comments

Comments

@robertfeldt
Copy link
Contributor

We applied our automated testing tool for testing a large number of functions in Julia Base and uncovered the below inconsistent behavior. We verified this on several versions including Julia 1.10.0-DEV.794, Julia 1.9.0-rc1, and Julia 1.8.5 and the behavior is the same for them all.

The problem seems to be that when one argument is negative and the other is an unsigned integer it will sometimes raise an exception, for UInt64 and UInt128, but other times not, for UInt8/Uint16/UInt32/BigInt. So likely with how type promotion is carried out when two arguments of different types. A corresponding inconsistency is also seen for Base.min.

I'd say the inconsistency is at least unexpected but even if not considered a bug maybe this should be noted somewhere in the documentation. Or maybe it is and I missed something? Thanks for any input/pointers.

Minimum working example (showing for 1.8.5 running on MacBook Pro 16 with M1Max but verified also for other versions, for all Julia versions I installed via dmg files from julialang.org):

julia> versioninfo()
Julia Version 1.8.5
Commit 17cfb8e65ea (2023-01-08 06:45 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin21.5.0)
  CPU: 10 × Apple M1 Max
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, apple-m1)
  Threads: 8 on 8 virtual cores
Environment:
  JULIA_NUM_THREADS = 8

julia> [Base.max(-1, T(0)) for T in [UInt8, UInt16, UInt32, BigInt]]
4-element Vector{Signed}:
 0
 0
 0
 0

julia> Base.max(-1, UInt64(0))
ERROR: InexactError: check_top_bit(UInt64, -1)
Stacktrace:
 [1] throw_inexacterror(f::Symbol, #unused#::Type{UInt64}, val::Int64)
   @ Core ./boot.jl:614
 [2] check_top_bit
   @ ./boot.jl:628 [inlined]
 [3] toUInt64
   @ ./boot.jl:739 [inlined]
 [4] UInt64
   @ ./boot.jl:769 [inlined]
 [5] convert
   @ ./number.jl:7 [inlined]
 [6] _promote
   @ ./promotion.jl:336 [inlined]
 [7] promote
   @ ./promotion.jl:359 [inlined]
 [8] max(x::Int64, y::UInt64)
   @ Base ./promotion.jl:437
 [9] top-level scope
   @ REPL[2]:1

julia> Base.max(-1, UInt128(0))
ERROR: InexactError: check_top_bit(UInt128, -1)
Stacktrace:
 [1] throw_inexacterror(f::Symbol, #unused#::Type{UInt128}, val::Int64)
   @ Core ./boot.jl:614
 [2] check_top_bit
   @ ./boot.jl:628 [inlined]
 [3] toUInt128
   @ ./boot.jl:750 [inlined]
 [4] UInt128
   @ ./boot.jl:770 [inlined]
 [5] convert
   @ ./number.jl:7 [inlined]
 [6] _promote
   @ ./promotion.jl:336 [inlined]
 [7] promote
   @ ./promotion.jl:359 [inlined]
 [8] max(x::Int64, y::UInt128)
   @ Base ./promotion.jl:437
 [9] top-level scope
   @ REPL[3]:1

julia> Base.min(-1, UInt64(0))
ERROR: InexactError: check_top_bit(UInt64, -1)
Stacktrace:
 [1] throw_inexacterror(f::Symbol, #unused#::Type{UInt64}, val::Int64)
   @ Core ./boot.jl:614
 [2] check_top_bit
   @ ./boot.jl:628 [inlined]
 [3] toUInt64
   @ ./boot.jl:739 [inlined]
 [4] UInt64
   @ ./boot.jl:769 [inlined]
 [5] convert
   @ ./number.jl:7 [inlined]
 [6] _promote
   @ ./promotion.jl:336 [inlined]
 [7] promote
   @ ./promotion.jl:359 [inlined]
 [8] min(x::Int64, y::UInt64)
   @ Base ./promotion.jl:438
 [9] top-level scope
   @ REPL[8]:1
@jakobnissen
Copy link
Contributor

It's not inconsistent - it promotes to the larger of the two types in all cases.
From the Julia documentation on promotion:

Integer values are promoted to the larger of either the native machine word size or the largest integer argument type. 

@robertfeldt
Copy link
Contributor Author

And the Unsigned type is considered larger if they have the same number of bits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants