Skip to content

Commit

Permalink
ndigits: add a 'pad' argument
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Aug 26, 2016
1 parent f17630b commit 95a4888
Showing 1 changed file with 22 additions and 17 deletions.
39 changes: 22 additions & 17 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ function prevpow(a::Real, x::Real)
p <= x ? p : a^n
end

## ndigits (number of digits) in base 10 ##

# decimal digits in an unsigned integer
const powers_of_ten = [
0x0000000000000001, 0x000000000000000a, 0x0000000000000064, 0x00000000000003e8,
Expand All @@ -218,8 +220,13 @@ end

ndigits0z(x::Signed) = ndigits0z(unsigned(abs(x)))

ndigits0z(x::Integer) = ndigits(x, false)
ndigits(x::Integer, min1::Bool=true) = x==0 ? min1%Int : ndigits0zpb(x, 10)
ndigits0z(x::Integer) = ndigits0zpb(x, 10)

# TODO (when keywords args are fast): rename to ndigits and make pad a keyword
ndigits10(x::Integer, pad::Int=1) = max(pad, ndigits0z(x))
ndigits(x::Integer) = x == 0 ? 1 : ndigits0z(x)

## ndigits with specified base ##

# The suffix "nb" stands for "negative base"
function ndigits0znb(n::Integer, b::Integer)
Expand Down Expand Up @@ -267,25 +274,23 @@ ndigits0zpb(x::Base.BitUnsigned, b::Integer) = ndigits0zpb(x, Int(b))
Return 0 if `n == 0`, otherwise compute the number of digits in number
`n` written in base `b`. The base `b` must not be in `[-1, 0, 1]`.
"""
ndigits0z(x::Integer, b::Integer) = ndigits(x, b, false)

"""
ndigits(n, b = 10)
Compute the number of digits in number `n` written in base `b`.
"""
function ndigits(x::Integer, b::Integer, min1::Bool=true)
# min1: whether the minimum value of this function should be 1
# (for the special input value 0), or not (then ndigits(0, b) == 0)
function ndigits0z(x::Integer, b::Integer)
if b < -1
x == 0 ? min1%Int : ndigits0znb(x, b)
ndigits0znb(x, b)
elseif b > 1
x == 0 ? min1%Int : ndigits0zpb(x, b)
ndigits0zpb(x, b)
else
throw(DomainError())
end
end

"""
ndigits(n, b = 10)
Compute the number of digits in number `n` written in base `b`.
"""
ndigits(x::Integer, b::Integer, pad::Int=1) = max(pad, ndigits0z(x, b))

## integer to string functions ##

string(x::Union{Int8,Int16,Int32,Int64,Int128}) = dec(x)
Expand Down Expand Up @@ -315,7 +320,7 @@ function oct(x::Unsigned, pad::Int, neg::Bool)
end

function dec(x::Unsigned, pad::Int, neg::Bool)
i = neg + max(pad,ndigits0z(x))
i = neg + ndigits10(x, pad)
a = Array{UInt8}(i)
while i > neg
a[i] = '0'+rem(x,10)
Expand Down Expand Up @@ -347,7 +352,7 @@ const base62digits = ['0':'9';'A':'Z';'a':'z']
function base(b::Int, x::Unsigned, pad::Int, neg::Bool)
2 <= b <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $b"))
digits = b <= 36 ? base36digits : base62digits
i = neg + max(pad,ndigits0z(x,b))
i = neg + ndigits(x, b, pad)
a = Array{UInt8}(i)
while i > neg
a[i] = digits[1+rem(x,b)]
Expand Down Expand Up @@ -379,7 +384,7 @@ bits(x::Union{Int128,UInt128}) = bin(reinterpret(UInt128,x),128)
digits{T<:Integer}(n::Integer, base::T=10, pad::Integer=1) = digits(T, n, base, pad)

function digits{T<:Integer}(::Type{T}, n::Integer, base::Integer=10, pad::Integer=1)
digits!(zeros(T, max(pad, ndigits0z(n,base))), n, base)
digits!(zeros(T, ndigits(n, base, pad)), n, base)
end

function digits!{T<:Integer}(a::AbstractArray{T,1}, n::Integer, base::Integer=10)
Expand Down

0 comments on commit 95a4888

Please sign in to comment.