From 049952886b21cd2911cb3e62f895c90a9c6cd376 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Sat, 15 Sep 2018 14:10:11 -0400 Subject: [PATCH] =?UTF-8?q?fix=20digits(n::Unsigned)=20with=20neg=20base?= =?UTF-8?q?=20for=20`n=20>=20typemax(n)=C3=B72`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alternative based on https://github.com/JuliaLang/julia/pull/29187 --- base/intfuncs.jl | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index a6f6ea05efe41d..8b9f3d441ec012 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -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