Skip to content

Commit

Permalink
fix digits(n::Unsigned) with neg base for n > typemax(n)÷2 (#29205)
Browse files Browse the repository at this point in the history
Alternative based on #29187

Tests from rforquet's PR linked above.
  • Loading branch information
StefanKarpinski authored Sep 17, 2018
1 parent 7d6bc6b commit 16516b5
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
24 changes: 16 additions & 8 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -744,17 +744,25 @@ julia> digits!([2,2,2,2,2,2], 10, base = 2)
```
"""
function digits!(a::AbstractVector{T}, n::Integer; base::Integer = 10) where T<:Integer
base < 0 && isa(n, Unsigned) && return digits!(a, convert(Signed, n), base = base)
2 <= abs(base) || throw(ArgumentError("base must be ≥ 2 or ≤ -2, got $base"))
hastypemax(T) && abs(base) - 1 > typemax(T) &&
throw(ArgumentError("type $T too small for base $base"))
for i in eachindex(a)
if base > 0
a[i] = rem(n, base)
n = div(n, base)
else
a[i] = mod(n, -base)
n = cld(n, base)
isempty(a) && return a

if base > 0
for i in eachindex(a)
n, d = divrem(n, base)
a[i] = d
end
else
# manually peel one loop iteration for type stability
n, d = fldmod(n, -base)
a[firstindex(a)] = d
n = -signed(n)
for i in firstindex(a)+1:lastindex(a)
n, d = fldmod(n, -base)
a[i] = d
n = -n
end
end
return a
Expand Down
9 changes: 8 additions & 1 deletion test/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,18 @@ end
@test digits(5, base = 3) == [2, 1]

@testset "digits/base with negative bases" begin
@testset "digits(n::$T, base = b)" for T in (Int, UInt, BigInt, Int32)
@testset "digits(n::$T, base = b)" for T in (Int, UInt, BigInt, Int32, UInt32)
@test digits(T(8163), base = -10) == [3, 4, 2, 2, 1]
if !(T<:Unsigned)
@test digits(T(-8163), base = -10) == [7, 7, 9, 9]
end
if T !== BigInt
b = rand(-32:-2)
for n = T[rand(T), typemax(T), typemin(T)]
# issue #29183
@test digits(n, base=b) == digits(signed(widen(n)), base=b)
end
end
end
@test [string(n, base = b)
for n = [-10^9, -10^5, -2^20, -2^10, -100, -83, -50, -34, -27, -16, -7, -3, -2, -1,
Expand Down

0 comments on commit 16516b5

Please sign in to comment.