Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Aug 17, 2016
1 parent 901d363 commit cff9e1b
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
2 changes: 1 addition & 1 deletion base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ function base(b::Integer, n::BigInt)
unsafe_wrap(String, p, true)
end

function ndigits0zpb(x::BigInt, b::Integer=10)
function ndigits0zpb(x::BigInt, b::Integer)
b < 2 && throw(DomainError())
x.size == 0 && return 0 # for consistency with other ndigits0z methods
if ispow2(b) && 2 <= b <= 62 # GMP assumes b is in this range
Expand Down
18 changes: 12 additions & 6 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ const powers_of_ten = [
0x000000e8d4a51000, 0x000009184e72a000, 0x00005af3107a4000, 0x00038d7ea4c68000,
0x002386f26fc10000, 0x016345785d8a0000, 0x0de0b6b3a7640000, 0x8ac7230489e80000,
]
function ndigits0z(x::Union{UInt8,UInt16,UInt32,UInt64})
function ndigits0z(x::Base.BitUnsigned64)
lz = (sizeof(x)<<3)-leading_zeros(x)
nd = (1233*lz)>>12+1
nd -= x < powers_of_ten[nd]
Expand All @@ -215,10 +215,11 @@ function ndigits0z(x::UInt128)
end
return n + ndigits0z(UInt64(x))
end
ndigits0z(x::Integer) = ndigits0z(unsigned(abs(x)))
ndigits(x::Integer) = x==0 ? 1 : ndigits0z(x)

const ndigits_max_mul = Core.sizeof(Int) == 4 ? 69000000 : 290000000000000000
ndigits0z(x::Base.BitSigned) = ndigits0z(unsigned(abs(x)))

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

# The suffix "nb" stands for "negative base"
function ndigits0znb(n::Integer, b::Integer)
Expand All @@ -233,6 +234,8 @@ end

ndigits0znb(n::Unsigned, b::Integer) = ndigits0znb(signed(n), b)

const ndigits_max_mul = Core.sizeof(Int) == 4 ? 69000000 : 290000000000000000

# The suffix "pb" stands for "positive base"
function ndigits0zpb(n::Unsigned, b::Int)
# precondition: b > 1
Expand All @@ -253,17 +256,20 @@ function ndigits0zpb(n::Unsigned, b::Int)
return d
end

ndigits0zpb(x::Integer, b::Integer) = ndigits0zpb(unsigned(abs(x)), Int(b))
ndigits0zpb(x::Signed, b::Integer) = ndigits0zpb(unsigned(abs(x)), Int(b))
ndigits0zpb(x::Unsigned, b::Integer) = ndigits0zpb(x, Int(b)) # TODO: test this path (from ndigits below)

# The suffix "0z" means that the ouput is 0 on input zero (cf. #16841)
"""
ndigits0z(n::Integer, b::Integer=10)
Return 0 if `n == 0`, otherwise compute the number of digits in number
`n` written in base `b`.
`n` written in base `b`. The base `b` must not be in `[-1, 0, 1]`.
"""
ndigits0z(x::Integer, b::Integer) = ndigits(x, b, false)

# 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 ndigits(x::Integer, b::Integer, min1::Bool=true)
if b < -1
x == 0 ? min1%Int : ndigits0znb(x, b)
Expand Down
6 changes: 3 additions & 3 deletions test/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ ndigits_mismatch(n) = ndigits(n) != ndigits(BigInt(n))
ndigits(big(rand(Int)), rand(63:typemax(Int)))
ndigits(big(rand(Int)), big(2)^rand(2:999))

for i in big([-20:-1;1:20; rand(Int)])
for b in -10:1
@test_throws DomainError ndigits(i, b)
for x in big([-20:20; rand(Int)])
for b in -1:1
@test_throws DomainError ndigits(x, b)
end
end

Expand Down
5 changes: 5 additions & 0 deletions test/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ for b in -1:1
@test_throws DomainError ndigits(rand(Int), b)
end

# test unsigned bases work
@test ndigits(9, 0x2) = 4
@test ndigits(0x9, 0x2) = 4


@test bin(3) == "11"
@test bin(3, 2) == "11"
@test bin(3, 3) == "011"
Expand Down

0 comments on commit cff9e1b

Please sign in to comment.