Skip to content

Commit 6eb1f42

Browse files
rfourquetjeffwong
authored andcommitted
digits!: check for typemax only when applicable (JuliaLang#16844)
1 parent 7b83a9c commit 6eb1f42

File tree

5 files changed

+19
-4
lines changed

5 files changed

+19
-4
lines changed

base/gmp.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor,
99
ndigits, promote_rule, rem, show, isqrt, string, powermod,
1010
sum, trailing_zeros, trailing_ones, count_ones, base, tryparse_internal,
1111
bin, oct, dec, hex, isequal, invmod, prevpow2, nextpow2, ndigits0zpb,
12-
widen, signed, unsafe_trunc, trunc, iszero, big, flipsign, signbit
12+
widen, signed, unsafe_trunc, trunc, iszero, big, flipsign, signbit, hastypemax
1313

1414
if Clong == Int32
1515
const ClongMax = Union{Int8, Int16, Int32}
@@ -228,6 +228,8 @@ signed(x::BigInt) = x
228228

229229
convert(::Type{BigInt}, x::BigInt) = x
230230

231+
hastypemax(::Type{BigInt}) = false
232+
231233
function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool)
232234
_n = Nullable{BigInt}()
233235

base/int.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const BitIntegerSmall = Union{BitIntegerSmall_types...}
2929
const BitSigned64T = Union{Type{Int8}, Type{Int16}, Type{Int32}, Type{Int64}}
3030
const BitUnsigned64T = Union{Type{UInt8}, Type{UInt16}, Type{UInt32}, Type{UInt64}}
3131

32+
const BitIntegerType = Union{map(T->Type{T}, BitInteger_types)...}
33+
3234
throw_inexacterror(f::Symbol, ::Type{T}, val) where T =
3335
(@_noinline_meta; throw(InexactError(f, T, val)))
3436

base/intfuncs.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,14 @@ function digits(T::Type{<:Integer}, n::Integer, base::Integer=10, pad::Integer=1
743743
digits!(zeros(T, ndigits(n, base, pad)), n, base)
744744
end
745745

746+
"""
747+
hastypemax(T::Type) -> Bool
748+
749+
Return `true` if and only if `typemax(T)` is defined.
750+
"""
751+
hastypemax(::Base.BitIntegerType) = true
752+
hastypemax(::Type{T}) where {T} = applicable(typemax, T)
753+
746754
"""
747755
digits!(array, n::Integer, base::Integer=10)
748756
@@ -772,7 +780,8 @@ julia> digits!([2,2,2,2,2,2], 10, 2)
772780
function digits!(a::AbstractVector{T}, n::Integer, base::Integer=10) where T<:Integer
773781
base < 0 && isa(n, Unsigned) && return digits!(a, convert(Signed, n), base)
774782
2 <= abs(base) || throw(ArgumentError("base must be ≥ 2 or ≤ -2, got $base"))
775-
abs(base) - 1 <= typemax(T) || throw(ArgumentError("type $T too small for base $base"))
783+
hastypemax(T) && abs(base) - 1 > typemax(T) &&
784+
throw(ArgumentError("type $T too small for base $base"))
776785
for i in eachindex(a)
777786
if base > 0
778787
a[i] = rem(n, base)

base/random.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ mutable struct Close1Open2 <: FloatInterval end
2828

2929
## RandomDevice
3030

31-
const BitIntegerType = Union{map(T->Type{T}, Base.BitInteger_types)...}
32-
const BoolBitIntegerType = Union{Type{Bool},BitIntegerType}
31+
const BoolBitIntegerType = Union{Type{Bool},Base.BitIntegerType}
3332
const BoolBitIntegerArray = Union{Array{Bool},Base.BitIntegerArray}
3433

3534
if Sys.iswindows()

test/bigint.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ end
289289

290290
@test Base.ndigits0zpb(big(0), big(rand(2:100))) == 0
291291

292+
# digits with BigInt bases (#16844)
293+
@test digits(big(2)^256, big(2)^128) == [0, 0, 1]
294+
292295
# conversion from float
293296
@test BigInt(2.0) == BigInt(2.0f0) == BigInt(big(2.0)) == 2
294297
@test_throws InexactError convert(BigInt, 2.1)

0 commit comments

Comments
 (0)