Skip to content

Commit 408b03d

Browse files
fix JuliaLang#36031: Printf bug for BigInt (JuliaLang#36033)
* fix JuliaLang#36031 * Apply suggestions from code review Co-authored-by: Simon Byrne <simonbyrne@gmail.com>
1 parent 98da056 commit 408b03d

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

stdlib/Printf/src/Printf.jl

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -942,10 +942,12 @@ function decode_0ct(x::BigInt, digits)
942942
pt = Base.ndigits0z(x, 8) + 1
943943
length(digits) < pt+1 && resize!(digits, pt+1)
944944
neg && (x.size = -x.size)
945-
p = convert(Ptr{UInt8}, digits) + 1
946-
GMP.MPZ.get_str!(p, 8, x)
945+
GC.@preserve digits begin
946+
p = pointer(digits,2)
947+
GMP.MPZ.get_str!(p, 8, x)
948+
end
947949
neg && (x.size = -x.size)
948-
return neg, Int32(pt), Int32(pt)
950+
return Int32(pt), Int32(pt), neg
949951
end
950952

951953
### decoding functions directly used by printf generated code ###
@@ -1059,13 +1061,16 @@ function ini_dec(x::BigInt, n::Int, digits)
10591061
end
10601062
d = Base.ndigits0z(x)
10611063
if d <= n
1062-
info = decode_dec(x)
1063-
d == n && return info
1064-
p = convert(Ptr{Cvoid}, digits) + info[2]
1065-
ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), p, '0', n - info[2])
1066-
return info
1064+
len,pt,neg = decode_dec(x, digits)
1065+
d == n && return (len,pt,neg)
1066+
1067+
GC.@preserve digits begin
1068+
ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), pointer(digits, pt+1), '0', n - pt)
1069+
end
1070+
return (len,pt,neg)
10671071
end
1068-
return (n, d, decode_dec(round(BigInt,x/big(10)^(d-n)))[3])
1072+
_, _, neg = decode_dec(round(BigInt,x/big(10)^(d-n)), digits)
1073+
return (n, d, neg)
10691074
end
10701075

10711076

stdlib/Printf/test/runtests.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ for (fmt, val) in (("%i", "42"),
3939
("%20a"," 0x2.ap+4"),
4040
("%-20a","0x2.ap+4 "),
4141
("%f", "42.000000"),
42-
("%g", "42")),
42+
("%g", "42"),
43+
("%e", "4.200000e+01")),
4344
num in (UInt16(42), UInt32(42), UInt64(42), UInt128(42),
4445
Int16(42), Int32(42), Int64(42), Int128(42), big"42")
45-
#big"42" causes stack overflow on %a ; gh #14409
46-
num isa BigInt && fmt in ["%a", "%#o", "%g"] && continue
4746
@test @eval(@sprintf($fmt, $num) == $val)
4847
end
4948

0 commit comments

Comments
 (0)