From fb2fd0b5d7968d5c11ed047122fcce0d06ac2f34 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 12 Sep 2023 12:23:19 -0400 Subject: [PATCH] Ryu: make sure adding zeros does not overwrite trailing dot (#51254) Fix #43129 (cherry picked from commit 832e46d923d4cf81351038a046e22f221b5e6120) --- base/ryu/exp.jl | 2 +- base/ryu/fixed.jl | 12 ++++++------ test/ryu.jl | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/base/ryu/exp.jl b/base/ryu/exp.jl index a3cb4eee68b22..fac48f63faa94 100644 --- a/base/ryu/exp.jl +++ b/base/ryu/exp.jl @@ -176,7 +176,7 @@ function writeexp(buf, pos, v::T, end roundUp = 0 if lastDigit != 5 - roundUp = lastDigit > 5 + roundUp = lastDigit > 5 ? 1 : 0 else rexp = precision - e requiredTwos = -e2 - rexp diff --git a/base/ryu/fixed.jl b/base/ryu/fixed.jl index 3aef032b3e0a8..a047545e2bc30 100644 --- a/base/ryu/fixed.jl +++ b/base/ryu/fixed.jl @@ -57,7 +57,7 @@ function writefixed(buf, pos, v::T, mant = bits & MANTISSA_MASK exp = Int((bits >> 52) & EXP_MASK) - if exp == 0 + if exp == 0 # subnormal e2 = 1 - 1023 - 52 m2 = mant else @@ -82,7 +82,7 @@ function writefixed(buf, pos, v::T, i = len - 1 while i >= 0 j = p10bits - e2 - #=@inbounds=# mula, mulb, mulc = POW10_SPLIT[POW10_OFFSET[idx + 1] + i + 1] + mula, mulb, mulc = POW10_SPLIT[POW10_OFFSET[idx + 1] + i + 1] digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8) if nonzero pos = append_nine_digits(digits, buf, pos) @@ -132,7 +132,7 @@ function writefixed(buf, pos, v::T, end break end - #=@inbounds=# mula, mulb, mulc = POW10_SPLIT_2[p + 1] + mula, mulb, mulc = POW10_SPLIT_2[p + 1] digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8) if i < blocks - 1 pos = append_nine_digits(digits, buf, pos) @@ -147,11 +147,11 @@ function writefixed(buf, pos, v::T, k += 1 end if lastDigit != 5 - roundUp = lastDigit > 5 + roundUp = lastDigit > 5 ? 1 : 0 else requiredTwos = -e2 - precision - 1 trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && pow2(m2, requiredTwos)) - roundUp = trailingZeros ? 2 : 1 + roundUp = trailingZeros ? 2 : 1 # 2 means round only if odd end if maximum > 0 pos = append_c_digits(maximum, digits, buf, pos) @@ -166,13 +166,13 @@ function writefixed(buf, pos, v::T, while true roundPos -= 1 if roundPos == (startpos - 1) || (buf[roundPos] == UInt8('-')) || (plus && buf[roundPos] == UInt8('+')) || (space && buf[roundPos] == UInt8(' ')) + buf[pos] = UInt8('0') buf[roundPos + 1] = UInt8('1') if dotPos > 1 buf[dotPos] = UInt8('0') buf[dotPos + 1] = decchar hasfractional = true end - buf[pos] = UInt8('0') pos += 1 break end diff --git a/test/ryu.jl b/test/ryu.jl index cf60e4867e236..86078dda99553 100644 --- a/test/ryu.jl +++ b/test/ryu.jl @@ -553,6 +553,11 @@ end # Float16 @test Ryu.writefixed(1.25e+5, 1, false, false, false, UInt8('.'), true) == "125000" @test Ryu.writefixed(1.25e+5, 2, false, false, false, UInt8('.'), true) == "125000" end + + @test Ryu.writefixed(100.0-eps(100.0), 0, false, false, true, UInt8('.'), false) == "100." + @test Ryu.writefixed(-100.0+eps(-100.0), 0, false, false, true, UInt8('.'), false) == "-100." + @test Ryu.writefixed(100.0-eps(100.0), 1, false, false, true, UInt8('.'), false) == "100.0" + @test Ryu.writefixed(-100.0+eps(-100.0), 1, false, false, true, UInt8('.'), false) == "-100.0" end # fixed @testset "Ryu.writeexp" begin