Skip to content

Commit

Permalink
fix base(b, big(0), 0) == "0"
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed May 30, 2017
1 parent 7c4edd3 commit 937b190
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 20 deletions.
32 changes: 13 additions & 19 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,27 +575,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)
b < 0 && return base(Int(b), n, 1, (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)
MPZ.get_str!(str, b, n)
end

function base(b::Integer, n::BigInt, pad::Integer)
function base(b::Integer, n::BigInt, pad::Integer=1)
b < 0 && return base(Int(b), n, pad, (b>0) & (n.size<0))
s = base(b, n)
buf = IOBuffer()
if n < 0
s = s[2:end]
write(buf, '-')
end
for i in 1:pad-sizeof(s) # `s` is known to be ASCII, and `length` is slower
write(buf, '0')
2 <= b <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $b"))
nd1 = ndigits(n, b)
nd = max(nd1, pad)
str = Base._string_n(nd + isneg(n) + 1) # +1 for final '\0'
ptr = pointer(str)
MPZ.get_str!(ptr + nd - nd1, b, n)
for i = (0:nd-nd1-1) + isneg(n)
unsafe_store!(ptr+i, '0' % UInt8)
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 ndigits0zpb(x::BigInt, b::Integer)
Expand Down
8 changes: 7 additions & 1 deletion test/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ end

# Issue #18849: bin, oct, dec, hex should not call sizeof on BigInts
# when padding is desired
let padding = 4, low = big(4), high = big(2^20)
let padding = 4, z = zero(BigInt), low = big(4), high = big(2^20)
@test bin(low, padding) == "0100"
@test oct(low, padding) == "0004"
@test dec(low, padding) == "0004"
Expand All @@ -339,6 +339,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 937b190

Please sign in to comment.