diff --git a/stdlib/Printf/src/Printf.jl b/stdlib/Printf/src/Printf.jl index ee40edd32c8b84..9d9a2c671ba872 100644 --- a/stdlib/Printf/src/Printf.jl +++ b/stdlib/Printf/src/Printf.jl @@ -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 = convert(Ptr{UInt8}, pointer(digits)) + 1 + 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 ### @@ -1059,13 +1061,16 @@ function ini_dec(x::BigInt, n::Int, digits) end d = Base.ndigits0z(x) if d <= n - info = decode_dec(x) + info = decode_dec(x, digits) 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]) + + GC.@preserve digits begin + p = convert(Ptr{Cvoid}, pointer(digits)) + info[2] + ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), p, '0', n - info[2]) + end return info end - return (n, d, decode_dec(round(BigInt,x/big(10)^(d-n)))[3]) + return (n, d, decode_dec(round(BigInt,x/big(10)^(d-n)), digits)[3]) end diff --git a/stdlib/Printf/test/runtests.jl b/stdlib/Printf/test/runtests.jl index e2b1e9ff4962d2..58d9451c3e2685 100644 --- a/stdlib/Printf/test/runtests.jl +++ b/stdlib/Printf/test/runtests.jl @@ -39,11 +39,12 @@ 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 + #num isa BigInt && fmt in ["%a", "%#o"] && continue @test @eval(@sprintf($fmt, $num) == $val) end