Skip to content

Commit

Permalink
fix #36031: Printf bug for BigInt (#36033)
Browse files Browse the repository at this point in the history
* fix #36031

* Apply suggestions from code review

Co-authored-by: Simon Byrne <[email protected]>
  • Loading branch information
simeonschaub and simonbyrne authored May 28, 2020
1 parent 8068e76 commit 150311f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
23 changes: 14 additions & 9 deletions stdlib/Printf/src/Printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -942,10 +942,12 @@ function decode_0ct(x::BigInt, digits)
pt = Base.ndigits0z(x, 8) + 1
length(digits) < pt+1 && resize!(digits, pt+1)
neg && (x.size = -x.size)
p = convert(Ptr{UInt8}, digits) + 1
GMP.MPZ.get_str!(p, 8, x)
GC.@preserve digits begin
p = pointer(digits,2)
GMP.MPZ.get_str!(p, 8, x)
end
neg && (x.size = -x.size)
return neg, Int32(pt), Int32(pt)
return Int32(pt), Int32(pt), neg
end

### decoding functions directly used by printf generated code ###
Expand Down Expand Up @@ -1059,13 +1061,16 @@ function ini_dec(x::BigInt, n::Int, digits)
end
d = Base.ndigits0z(x)
if d <= n
info = decode_dec(x)
d == n && return info
p = convert(Ptr{Cvoid}, digits) + info[2]
ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), p, '0', n - info[2])
return info
len,pt,neg = decode_dec(x, digits)
d == n && return (len,pt,neg)

GC.@preserve digits begin
ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), pointer(digits, pt+1), '0', n - pt)
end
return (len,pt,neg)
end
return (n, d, decode_dec(round(BigInt,x/big(10)^(d-n)))[3])
_, _, neg = decode_dec(round(BigInt,x/big(10)^(d-n)), digits)
return (n, d, neg)
end


Expand Down
5 changes: 2 additions & 3 deletions stdlib/Printf/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ for (fmt, val) in (("%i", "42"),
("%20a"," 0x2.ap+4"),
("%-20a","0x2.ap+4 "),
("%f", "42.000000"),
("%g", "42")),
("%g", "42"),
("%e", "4.200000e+01")),
num in (UInt16(42), UInt32(42), UInt64(42), UInt128(42),
Int16(42), Int32(42), Int64(42), Int128(42), big"42")
#big"42" causes stack overflow on %a ; gh #14409
num isa BigInt && fmt in ["%a", "%#o", "%g"] && continue
@test @eval(@sprintf($fmt, $num) == $val)
end

Expand Down

0 comments on commit 150311f

Please sign in to comment.