Skip to content

Commit

Permalink
fix base(b, big(0), 0) == "0"
Browse files Browse the repository at this point in the history
Ref #22133
(cherry picked from commit 994f42c)
  • Loading branch information
rfourquet authored and ararslan committed Sep 14, 2017
1 parent acba61a commit 29cc5b0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
31 changes: 13 additions & 18 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -578,26 +578,21 @@ oct(n::BigInt, pad::Int) = base( 8, n, pad)
dec(n::BigInt, pad::Int) = base(10, n, pad)
hex(n::BigInt, pad::Int) = base(16, n, pad)

function base(b::Integer, n::BigInt)
function base(b::Integer, n::BigInt, pad::Integer=1)
b < 0 && return base(Int(b), n, pad, (b>0) & (n.size<0))
2 <= b <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $b"))
nd = ndigits(n, b)
str = Base._string_n(n < 0 ? nd+1 : nd)
ccall((:__gmpz_get_str,:libgmp), Ptr{UInt8}, (Ptr{UInt8}, Cint, Ptr{BigInt}), str, b, &n)
return str
end

function base(b::Integer, n::BigInt, pad::Integer)
s = base(b, n)
buf = IOBuffer()
if n < 0
s = s[2:end]
write(buf, '-')
nd1 = ndigits(n, b)
nd = max(nd1, pad)
str = Base._string_n(nd + isneg(n) + 1) # +1 for final '\0'
ptr = pointer(str)
ccall((:__gmpz_get_str,:libgmp), Ptr{UInt8}, (Ptr{UInt8}, Cint, Ref{BigInt}), ptr + nd - nd1, b, n)
for i = (0:nd-nd1-1) + isneg(n)
unsafe_store!(ptr+i, '0' % UInt8)
end
for i in 1:pad-sizeof(s) # `s` is known to be ASCII, and `length` is slower
write(buf, '0')
end
write(buf, s)
String(buf)
isneg(n) && unsafe_store!(ptr, '-' % UInt8)
str.len -= 1 # final '\0'
iszero(n) && pad < 1 && (str.len -= 1)
str
end

function ndigits0z(x::BigInt, b::Integer=10)
Expand Down
6 changes: 6 additions & 0 deletions test/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ let padding = 4, low = big(4), high = big(2^20)
@test hex(-high, padding) == "-100000"
end

# respect 0-padding on big(0)
for f in (bin, oct, dec, hex)
@test f(big(0), 0) == ""
end
@test base(rand(2:62), big(0), 0) == ""

@test isqrt(big(4)) == 2
@test isqrt(big(5)) == 2

Expand Down

0 comments on commit 29cc5b0

Please sign in to comment.