diff --git a/base/ryu/Ryu.jl b/base/ryu/Ryu.jl index c08e58d9c97727..7fabe5b991513f 100644 --- a/base/ryu/Ryu.jl +++ b/base/ryu/Ryu.jl @@ -10,27 +10,32 @@ shortestdigits(::Type{Float32}) = 39 + 9 shortestdigits(::Type{Float16}) = 9 + 5 function writeshortest(x::T) where {T <: Base.IEEEFloat} - buf, pos = writeshortest(x, Vector{UInt8}(undef, shortestdigits(T)), 1) - return String(buf[1:pos-1]) + buf = Vector{UInt8}(undef, shortestdigits(T)) + pos = writeshortest(x, buf, 1) + return unsafe_string(pointer(buf), pos-1) end function writefixed(x::T, precision) where {T <: Base.IEEEFloat} - buf, pos = writefixed(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1) - return String(buf[1:pos-1]) + buf = Vector{UInt8}(undef, precision + shortestdigits(T)) + pos = writefixed(x, precision, buf, 1) + return unsafe_string(pointer(buf), pos-1) end function writeexp(x::T, precision) where {T <: Base.IEEEFloat} - buf, pos = writeexp(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1) - return String(buf[1:pos-1]) + buf = Vector{UInt8}(undef, precision + shortestdigits(T)) + pos = writeexp(x, precision, buf, 1) + return unsafe_string(pointer(buf), pos-1) end function Base.show(io::IO, x::T) where {T <: Base.IEEEFloat} if get(io, :compact, false) precision = T == Float16 ? 5 : 6 - buf, pos = writefixed(x, precision, Vector{UInt8}(undef, precision + shortestdigits(T)), 1) + buf = Vector{UInt8}(undef, precision + shortestdigits(T)) + pos = writefixed(x, precision, buf, 1) GC.@preserve buf unsafe_write(io, pointer(buf), pos - 1) else - buf, pos = writeshortest(x, Vector{UInt8}(undef, shortestdigits(T)), 1) + buf = Vector{UInt8}(undef, shortestdigits(T)) + pos = writeshortest(x, buf, 1) GC.@preserve buf unsafe_write(io, pointer(buf), pos - 1) end return diff --git a/base/ryu/exp.jl b/base/ryu/exp.jl index e457a8ef109dc2..042adcdf2b6b5b 100644 --- a/base/ryu/exp.jl +++ b/base/ryu/exp.jl @@ -21,12 +21,12 @@ buf[pos + 1] = UInt8('+') buf[pos + 2] = UInt8('0') buf[pos + 3] = UInt8('0') - return buf, pos + 4 + return pos + 4 elseif isnan(x) buf[pos] = UInt8('N') buf[pos + 1] = UInt8('a') buf[pos + 2] = UInt8('N') - return buf, pos + 3 + return pos + 3 elseif !isfinite(x) if neg buf[pos] = UInt8('-') @@ -34,7 +34,7 @@ buf[pos + neg] = UInt8('I') buf[pos + neg + 1] = UInt8('n') buf[pos + neg + 2] = UInt8('f') - return buf, pos + neg + 3 + return pos + neg + 3 end bits = Core.bitcast(UInt64, x) @@ -212,5 +212,5 @@ unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * e + 1, 2) pos += 2 end - return buf, pos + return pos end diff --git a/base/ryu/fixed.jl b/base/ryu/fixed.jl index fff88cb26bd08c..a2a072a148e273 100644 --- a/base/ryu/fixed.jl +++ b/base/ryu/fixed.jl @@ -17,12 +17,12 @@ pos += 1 end end - return buf, pos + return pos elseif isnan(x) buf[pos] = UInt8('N') buf[pos + 1] = UInt8('a') buf[pos + 2] = UInt8('N') - return buf, pos + 3 + return pos + 3 elseif !isfinite(x) if neg buf[pos] = UInt8('-') @@ -30,7 +30,7 @@ buf[pos + neg] = UInt8('I') buf[pos + neg + 1] = UInt8('n') buf[pos + neg + 2] = UInt8('f') - return buf, pos + neg + 3 + return pos + neg + 3 end bits = Core.bitcast(UInt64, x) @@ -170,5 +170,5 @@ pos += 1 end end - return buf, pos + return pos end diff --git a/base/ryu/shortest.jl b/base/ryu/shortest.jl index 907416154c78ca..60be795e130ead 100644 --- a/base/ryu/shortest.jl +++ b/base/ryu/shortest.jl @@ -8,12 +8,12 @@ buf[pos + neg] = UInt8('0') buf[pos + neg + 1] = UInt8('.') buf[pos + neg + 2] = UInt8('0') - return buf, pos + neg + 3 + return pos + neg + 3 elseif isnan(x) buf[pos] = UInt8('N') buf[pos + 1] = UInt8('a') buf[pos + 2] = UInt8('N') - return buf, pos + 3 + return pos + 3 elseif !isfinite(x) if neg buf[pos] = UInt8('-') @@ -21,7 +21,7 @@ buf[pos + neg] = UInt8('I') buf[pos + neg + 1] = UInt8('n') buf[pos + neg + 2] = UInt8('f') - return buf, pos + neg + 3 + return pos + neg + 3 end bits = uint(x) @@ -176,77 +176,115 @@ end olength = decimallength(output) + exp_form = true + pt = nexp + olength + if -4 < pt < 6 && !(pt >= olength && abs(mod(x + 0.05, 10^(pt - olength)) - 0.05) > 0.05) + exp_form = false + # print out digits and decimal point fully + if nexp >= 0 + buf[pos + nexp + olength] = UInt8('.') + buf[pos + nexp + olength + 1] = UInt8('0') + elseif abs(nexp) >= olength + buf[pos] = UInt8('0') + buf[pos + 1] = UInt8('.') + pos += 2 + for _ = 1:(abs(nexp) - olength) + buf[pos] = UInt8('0') + pos += 1 + end + end + else + pos += 1 + end i = 0 + ptr = pointer(buf) + ptr2 = pointer(DIGIT_TABLE) if (output >> 32) != 0 q = output ÷ 100000000 output2 = (output % UInt32) - UInt32(100000000) * (q % UInt32) output = q - c = output2 % 10000 - output2 = div(output2, 10000) - d = output2 % 10000 + c = output2 % UInt32(10000) + output2 = div(output2, UInt32(10000)) + d = output2 % UInt32(10000) c0 = (c % 100) << 1 c1 = (c ÷ 100) << 1 d0 = (d % 100) << 1 d1 = (d ÷ 100) << 1 - unsafe_copyto!(buf, pos + olength - 1, DIGIT_TABLE, c0 + 1, 2) - unsafe_copyto!(buf, pos + olength - 3, DIGIT_TABLE, c1 + 1, 2) - unsafe_copyto!(buf, pos + olength - 5, DIGIT_TABLE, d0 + 1, 2) - unsafe_copyto!(buf, pos + olength - 7, DIGIT_TABLE, d1 + 1, 2) + memcpy(ptr, pos + olength - 2, ptr2, c0 + 1, 2) + memcpy(ptr, pos + olength - 4, ptr2, c1 + 1, 2) + memcpy(ptr, pos + olength - 6, ptr2, d0 + 1, 2) + memcpy(ptr, pos + olength - 8, ptr2, d1 + 1, 2) i += 8 end output2 = output % UInt32 while output2 >= 10000 - c = output2 % 10000 - output2 = div(output2, 10000) + c = output2 % UInt32(10000) + output2 = div(output2, UInt32(10000)) c0 = (c % 100) << 1 c1 = (c ÷ 100) << 1 - unsafe_copyto!(buf, pos + olength - i - 1, DIGIT_TABLE, c0 + 1, 2) - unsafe_copyto!(buf, pos + olength - i - 3, DIGIT_TABLE, c1 + 1, 2) + memcpy(ptr, pos + olength - i - 2, ptr2, c0 + 1, 2) + memcpy(ptr, pos + olength - i - 4, ptr2, c1 + 1, 2) i += 4 end if output2 >= 100 - c = (output2 % 100) << 1 - output2 = div(output2, 100) - unsafe_copyto!(buf, pos + olength - i - 1, DIGIT_TABLE, c + 1, 2) + c = (output2 % UInt32(100)) << 1 + output2 = div(output2, UInt32(100)) + memcpy(ptr, pos + olength - i - 2, ptr2, c + 1, 2) i += 2 end if output2 >= 10 c = output2 << 1 - #=@inbounds=# buf[pos + olength - i] = DIGIT_TABLE[c + 2] - #=@inbounds=# buf[pos] = DIGIT_TABLE[c + 1] + #=@inbounds=# buf[pos + 1] = DIGIT_TABLE[c + 2] + #=@inbounds=# buf[pos - exp_form] = DIGIT_TABLE[c + 1] else - #=@inbounds=# buf[pos] = UInt8('0') + (output2 % UInt8) + #=@inbounds=# buf[pos - exp_form] = UInt8('0') + (output2 % UInt8) end - if olength > 1 - #=@inbounds=# buf[pos + 1] = UInt8('.') - pos += olength + 1 + if !exp_form + if nexp >= 0 + pos += olength + for _ = 1:nexp + buf[pos] = UInt8('0') + pos += 1 + end + pos += 2 + elseif olength > abs(nexp) + pointoff = olength - abs(nexp) + memmove(ptr, pos + pointoff + 1, ptr, pos + pointoff, olength - pointoff + 1) + buf[pos + pointoff] = UInt8('.') + pos += olength + 1 + else + pos += olength + end else - pos += 1 - end + if olength > 1 + #=@inbounds=# buf[pos] = UInt8('.') + pos += olength + end - #=@inbounds=# buf[pos] = UInt8('e') - pos += 1 - exp2 = nexp + olength - 1 - if exp2 < 0 - #=@inbounds=# buf[pos] = UInt8('-') + #=@inbounds=# buf[pos] = UInt8('e') pos += 1 - exp2 = -exp2 - end + exp2 = nexp + olength - 1 + if exp2 < 0 + #=@inbounds=# buf[pos] = UInt8('-') + pos += 1 + exp2 = -exp2 + end - if exp2 >= 100 - c = exp2 % 10 - unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * div(exp2, 10) + 1, 2) - #=@inbounds=# buf[pos + 2] = UInt8('0') + (c % UInt8) - pos += 3 - elseif exp2 >= 10 - unsafe_copyto!(buf, pos, DIGIT_TABLE, 2 * exp2 + 1, 2) - pos += 2 - else - #=@inbounds=# buf[pos] = UInt8('0') + (exp2 % UInt8) - pos += 1 + if exp2 >= 100 + c = exp2 % 10 + memcpy(ptr, pos, ptr2, 2 * div(exp2, 10) + 1, 2) + #=@inbounds=# buf[pos + 2] = UInt8('0') + (c % UInt8) + pos += 3 + elseif exp2 >= 10 + memcpy(ptr, pos, ptr2, 2 * exp2 + 1, 2) + pos += 2 + else + #=@inbounds=# buf[pos] = UInt8('0') + (exp2 % UInt8) + pos += 1 + end end - return buf, pos + return pos end \ No newline at end of file diff --git a/base/ryu/utils.jl b/base/ryu/utils.jl index 1046584e5efbc7..f50d1f227abdf7 100644 --- a/base/ryu/utils.jl +++ b/base/ryu/utils.jl @@ -1,6 +1,9 @@ const MANTISSA_MASK = 0x000fffffffffffff const EXP_MASK = 0x00000000000007ff +memcpy(d, doff, s, soff, n) = ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Int), d + doff - 1, s + soff - 1, n) +memmove(d, doff, s, soff, n) = ccall(:memmove, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Int), d + doff - 1, s + soff - 1, n) + uint(x::Float16) = Core.bitcast(UInt16, x) uint(x::Float32) = Core.bitcast(UInt32, x) uint(x::Float64) = Core.bitcast(UInt64, x) @@ -36,9 +39,9 @@ qbound(::Type{Float64}) = 63 log10pow2(e) = (e * 78913) >> 18 log10pow5(e) = (e * 732923) >> 20 pow5bits(e) = ((e * 1217359) >> 19) + 1 -mulshift(m::UInt64, mula, mulb, j) = ((((UInt128(m) * mula) >> 64) + UInt128(m) * mulb) >> (j - 64)) % UInt64 -mulshift(m::UInt32, mul, j) = ((((UInt64(m) * (mul % UInt32)) >> 32) + (UInt64(m) * (mul >> 32))) >> (j - 32)) % UInt32 -mulshift(m::UInt16, mul, j) = ((((UInt32(m) * (mul % UInt16)) >> 16) + (UInt32(m) * (mul >> 16))) >> (j - 16)) +@inline mulshift(m::UInt64, mula, mulb, j) = ((((UInt128(m) * mula) >> 64) + UInt128(m) * mulb) >> (j - 64)) % UInt64 +@inline mulshift(m::UInt32, mul, j) = ((((UInt64(m) * (mul % UInt32)) >> 32) + (UInt64(m) * (mul >> 32))) >> (j - 32)) % UInt32 +@inline mulshift(m::UInt16, mul, j) = ((((UInt32(m) * (mul % UInt16)) >> 16) + (UInt32(m) * (mul >> 16))) >> (j - 16)) indexforexp(e) = div(e + 15, 16) pow10bitsforindex(idx) = 16 * idx + 120 lengthforindex(idx) = div((((16 * idx) * 1292913986) >> 32) + 1 + 16 + 8, 9) @@ -284,7 +287,7 @@ const BIG_MASK = (big(1) << 64) - 1 const POW10_SPLIT = collect(Iterators.flatten(map(0:63) do idx pow10bits = pow10bitsforindex(idx) - map(0:lengthforindex(idx)-1) do i + map(0:lengthforindex(idx) - 1) do i v = (div(big(1) << pow10bits, big(10)^(9 * i)) + 1) % ((big(10)^9) << 136) return (UInt64(v & BIG_MASK), UInt64((v >> 64) & BIG_MASK), UInt64((v >> 128) & BIG_MASK)) end @@ -325,7 +328,7 @@ bitlength(this) = Base.GMP.MPZ.sizeinbase(this, 2) @inline function pow5invsplit(::Type{Float64}, i) pow = big(5)^i inv = div(big(1) << (bitlength(pow) - 1 + pow5_inv_bitcount(Float64)), pow) + 1 - return (inv & ((big(1) << 64) - 1), inv >> 64) + return (UInt64(inv & ((big(1) << 64) - 1)), UInt64(inv >> 64)) end @inline function pow5invsplit(::Type{Float32}, i) @@ -343,7 +346,7 @@ end @inline function pow5split(::Type{Float64}, i) pow = big(5)^i j = bitlength(pow) - pow5_bitcount(Float64) - return ((pow >> j) & ((big(1) << 64) - 1), pow >> (j + 64)) + return (UInt64((pow >> j) & ((big(1) << 64) - 1)), UInt64(pow >> (j + 64))) end @inline function pow5split(::Type{Float32}, i) diff --git a/test/ryu.jl b/test/ryu.jl index 083341fc502f52..9e91ec82c84161 100644 --- a/test/ryu.jl +++ b/test/ryu.jl @@ -10,8 +10,8 @@ todouble(sign, exp, mant) = Core.bitcast(Float64, (UInt64(sign) << 63) | (UInt64 @testset "Basic" begin @test Ryu.writeshortest(0.0) == "0.0" @test Ryu.writeshortest(-0.0) == "-0.0" - @test Ryu.writeshortest(1.0) == "1e0" - @test Ryu.writeshortest(-1.0) == "-1e0" + @test Ryu.writeshortest(1.0) == "1.0" + @test Ryu.writeshortest(-1.0) == "-1.0" @test Ryu.writeshortest(NaN) == "NaN" @test Ryu.writeshortest(Inf) == "Inf" @test Ryu.writeshortest(-Inf) == "-Inf" @@ -38,7 +38,7 @@ end @test "9.0608011534336e15" == Ryu.writeshortest(9.0608011534336e15) @test "4.708356024711512e18" == Ryu.writeshortest(4.708356024711512e18) @test "9.409340012568248e18" == Ryu.writeshortest(9.409340012568248e18) - @test "1.2345678e0" == Ryu.writeshortest(1.2345678) + @test "1.2345678" == Ryu.writeshortest(1.2345678) end @testset "LooksLikePow5" begin @@ -51,30 +51,30 @@ end end @testset "OutputLength" begin - @test "1e0" == Ryu.writeshortest(1.0) # already tested in Basic - @test "1.2e0" == Ryu.writeshortest(1.2) - @test "1.23e0" == Ryu.writeshortest(1.23) - @test "1.234e0" == Ryu.writeshortest(1.234) - @test "1.2345e0" == Ryu.writeshortest(1.2345) - @test "1.23456e0" == Ryu.writeshortest(1.23456) - @test "1.234567e0" == Ryu.writeshortest(1.234567) - @test "1.2345678e0" == Ryu.writeshortest(1.2345678) # already tested in Regressi - @test "1.23456789e0" == Ryu.writeshortest(1.23456789) - @test "1.234567895e0" == Ryu.writeshortest(1.234567895) # 1.234567890 would be trimm - @test "1.2345678901e0" == Ryu.writeshortest(1.2345678901) - @test "1.23456789012e0" == Ryu.writeshortest(1.23456789012) - @test "1.234567890123e0" == Ryu.writeshortest(1.234567890123) - @test "1.2345678901234e0" == Ryu.writeshortest(1.2345678901234) - @test "1.23456789012345e0" == Ryu.writeshortest(1.23456789012345) - @test "1.234567890123456e0" == Ryu.writeshortest(1.234567890123456) - @test "1.2345678901234567e0" == Ryu.writeshortest(1.2345678901234567) + @test "1.0" == Ryu.writeshortest(1.0) # already tested in Basic + @test "1.2" == Ryu.writeshortest(1.2) + @test "1.23" == Ryu.writeshortest(1.23) + @test "1.234" == Ryu.writeshortest(1.234) + @test "1.2345" == Ryu.writeshortest(1.2345) + @test "1.23456" == Ryu.writeshortest(1.23456) + @test "1.234567" == Ryu.writeshortest(1.234567) + @test "1.2345678" == Ryu.writeshortest(1.2345678) # already tested in Regressi + @test "1.23456789" == Ryu.writeshortest(1.23456789) + @test "1.234567895" == Ryu.writeshortest(1.234567895) # 1.234567890 would be trimm + @test "1.2345678901" == Ryu.writeshortest(1.2345678901) + @test "1.23456789012" == Ryu.writeshortest(1.23456789012) + @test "1.234567890123" == Ryu.writeshortest(1.234567890123) + @test "1.2345678901234" == Ryu.writeshortest(1.2345678901234) + @test "1.23456789012345" == Ryu.writeshortest(1.23456789012345) + @test "1.234567890123456" == Ryu.writeshortest(1.234567890123456) + @test "1.2345678901234567" == Ryu.writeshortest(1.2345678901234567) # Test 32-bit chunking - @test "4.294967294e0" == Ryu.writeshortest(4.294967294) # 2^32 - - @test "4.294967295e0" == Ryu.writeshortest(4.294967295) # 2^32 - - @test "4.294967296e0" == Ryu.writeshortest(4.294967296) # 2^ - @test "4.294967297e0" == Ryu.writeshortest(4.294967297) # 2^32 + - @test "4.294967298e0" == Ryu.writeshortest(4.294967298) # 2^32 + + @test "4.294967294" == Ryu.writeshortest(4.294967294) # 2^32 - + @test "4.294967295" == Ryu.writeshortest(4.294967295) # 2^32 - + @test "4.294967296" == Ryu.writeshortest(4.294967296) # 2^ + @test "4.294967297" == Ryu.writeshortest(4.294967297) # 2^32 + + @test "4.294967298" == Ryu.writeshortest(4.294967298) # 2^32 + end # Test min, max shift values in shiftright128 @@ -133,11 +133,11 @@ end @test "9.007199254740991e15" == Ryu.writeshortest(9007199254740991.0) @test "9.007199254740992e15" == Ryu.writeshortest(9007199254740992.0) - @test "1e0" == Ryu.writeshortest(1.0e+0) - @test "1.2e1" == Ryu.writeshortest(1.2e+1) - @test "1.23e2" == Ryu.writeshortest(1.23e+2) - @test "1.234e3" == Ryu.writeshortest(1.234e+3) - @test "1.2345e4" == Ryu.writeshortest(1.2345e+4) + @test "1.0" == Ryu.writeshortest(1.0e+0) + @test "12.0" == Ryu.writeshortest(1.2e+1) + @test "123.0" == Ryu.writeshortest(1.23e+2) + @test "1234.0" == Ryu.writeshortest(1.234e+3) + @test "12345.0" == Ryu.writeshortest(1.2345e+4) @test "1.23456e5" == Ryu.writeshortest(1.23456e+5) @test "1.234567e6" == Ryu.writeshortest(1.234567e+6) @test "1.2345678e7" == Ryu.writeshortest(1.2345678e+7) @@ -152,11 +152,11 @@ end @test "1.234567890123456e15" == Ryu.writeshortest(1.234567890123456e+15) # 10^i - @test "1e0" == Ryu.writeshortest(1.0e+0) - @test "1e1" == Ryu.writeshortest(1.0e+1) - @test "1e2" == Ryu.writeshortest(1.0e+2) - @test "1e3" == Ryu.writeshortest(1.0e+3) - @test "1e4" == Ryu.writeshortest(1.0e+4) + @test "1.0" == Ryu.writeshortest(1.0e+0) + @test "10.0" == Ryu.writeshortest(1.0e+1) + @test "100.0" == Ryu.writeshortest(1.0e+2) + @test "1000.0" == Ryu.writeshortest(1.0e+3) + @test "10000.0" == Ryu.writeshortest(1.0e+4) @test "1e5" == Ryu.writeshortest(1.0e+5) @test "1e6" == Ryu.writeshortest(1.0e+6) @test "1e7" == Ryu.writeshortest(1.0e+7) @@ -187,11 +187,11 @@ end @test "1.1e15" == Ryu.writeshortest(1.0e+15 + 1.0e+14) # Largest power of 2 <= 10^(i+1) - @test "8e0" == Ryu.writeshortest(8.0) - @test "6.4e1" == Ryu.writeshortest(64.0) - @test "5.12e2" == Ryu.writeshortest(512.0) - @test "8.192e3" == Ryu.writeshortest(8192.0) - @test "6.5536e4" == Ryu.writeshortest(65536.0) + @test "8.0" == Ryu.writeshortest(8.0) + @test "64.0" == Ryu.writeshortest(64.0) + @test "512.0" == Ryu.writeshortest(512.0) + @test "8192.0" == Ryu.writeshortest(8192.0) + @test "65536.0" == Ryu.writeshortest(65536.0) @test "5.24288e5" == Ryu.writeshortest(524288.0) @test "8.388608e6" == Ryu.writeshortest(8388608.0) @test "6.7108864e7" == Ryu.writeshortest(67108864.0) @@ -205,8 +205,8 @@ end @test "9.007199254740992e15" == Ryu.writeshortest(9007199254740992.0) # 1000 * (Largest power of 2 <= 10^(i+1)) - @test "8e3" == Ryu.writeshortest(8.0e+3) - @test "6.4e4" == Ryu.writeshortest(64.0e+3) + @test "8000.0" == Ryu.writeshortest(8.0e+3) + @test "64000.0" == Ryu.writeshortest(64.0e+3) @test "5.12e5" == Ryu.writeshortest(512.0e+3) @test "8.192e6" == Ryu.writeshortest(8192.0e+3) @test "6.5536e7" == Ryu.writeshortest(65536.0e+3) @@ -227,8 +227,8 @@ end # Float64 @testset "Basic" begin @test "0.0" == Ryu.writeshortest(Float32(0.0)) @test "-0.0" == Ryu.writeshortest(Float32(-0.0)) - @test "1e0" == Ryu.writeshortest(Float32(1.0)) - @test "-1e0" == Ryu.writeshortest(Float32(-1.0)) + @test "1.0" == Ryu.writeshortest(Float32(1.0)) + @test "-1.0" == Ryu.writeshortest(Float32(-1.0)) @test "NaN" == Ryu.writeshortest(Float32(NaN)) @test "Inf" == Ryu.writeshortest(Float32(Inf)) @test "-Inf" == Ryu.writeshortest(Float32(-Inf)) @@ -256,15 +256,15 @@ end # last two digits are ...2|5 or ...7|5, and we cut off the 5. @testset "exactValueRoundeven" begin @test "3.0540412e5" == Ryu.writeshortest(3.0540412f5) - @test "8.0990312e3" == Ryu.writeshortest(8.0990312f3) + @test "8099.0312" == Ryu.writeshortest(8.0990312f3) end @testset "LotsOfTrailingZeros" begin # Pattern for the first test: 00111001100000000000000000000000 - @test "2.4414062e-4" == Ryu.writeshortest(2.4414062f-4) - @test "2.4414062e-3" == Ryu.writeshortest(2.4414062f-3) - @test "4.3945312e-3" == Ryu.writeshortest(4.3945312f-3) - @test "6.3476562e-3" == Ryu.writeshortest(6.3476562f-3) + @test "0.00024414062" == Ryu.writeshortest(2.4414062f-4) + @test "0.0024414062" == Ryu.writeshortest(2.4414062f-3) + @test "0.0043945312" == Ryu.writeshortest(4.3945312f-3) + @test "0.0063476562" == Ryu.writeshortest(6.3476562f-3) end @testset "Regression" begin @@ -276,10 +276,10 @@ end @test "1.9310392e-38" == Ryu.writeshortest(1.9310392f-38) @test "-2.47e-43" == Ryu.writeshortest(-2.47f-43) @test "1.993244e-38" == Ryu.writeshortest(1.993244f-38) - @test "4.1039004e3" == Ryu.writeshortest(4103.9003f0) + @test "4103.9004" == Ryu.writeshortest(4103.9003f0) @test "5.3399997e9" == Ryu.writeshortest(5.3399997f9) @test "6.0898e-39" == Ryu.writeshortest(6.0898f-39) - @test "1.0310042e-3" == Ryu.writeshortest(0.0010310042f0) + @test "0.0010310042" == Ryu.writeshortest(0.0010310042f0) @test "2.882326e17" == Ryu.writeshortest(2.8823261f17) @test "7.038531e-26" == Ryu.writeshortest(7.0385309f-26) @test "9.223404e17" == Ryu.writeshortest(9.2234038f17) @@ -291,11 +291,11 @@ end @test "1.1811161e19" == Ryu.writeshortest(1.1811161f19) @test "5.368709e18" == Ryu.writeshortest(5.368709f18) @test "4.6143166e18" == Ryu.writeshortest(4.6143165f18) - @test "7.812537e-3" == Ryu.writeshortest(0.007812537f0) + @test "0.007812537" == Ryu.writeshortest(0.007812537f0) @test "1e-45" == Ryu.writeshortest(1.4f-45) @test "1.18697725e20" == Ryu.writeshortest(1.18697724f20) @test "1.00014165e-36" == Ryu.writeshortest(1.00014165f-36) - @test "2e2" == Ryu.writeshortest(200f0) + @test "200.0" == Ryu.writeshortest(200f0) @test "3.3554432e7" == Ryu.writeshortest(3.3554432f7) end @@ -309,14 +309,14 @@ end end @testset "OutputLength" begin - @test "1e0" == Ryu.writeshortest(Float32(1.0)) - @test "1.2e0" == Ryu.writeshortest(Float32(1.2)) - @test "1.23e0" == Ryu.writeshortest(Float32(1.23)) - @test "1.234e0" == Ryu.writeshortest(Float32(1.234)) - @test "1.2345e0" == Ryu.writeshortest(Float32(1.2345)) - @test "1.23456e0" == Ryu.writeshortest(Float32(1.23456)) - @test "1.234567e0" == Ryu.writeshortest(Float32(1.234567)) - @test "1.2345678e0" == Ryu.writeshortest(Float32(1.2345678)) + @test "1.0" == Ryu.writeshortest(Float32(1.0)) + @test "1.2" == Ryu.writeshortest(Float32(1.2)) + @test "1.23" == Ryu.writeshortest(Float32(1.23)) + @test "1.234" == Ryu.writeshortest(Float32(1.234)) + @test "1.2345" == Ryu.writeshortest(Float32(1.2345)) + @test "1.23456" == Ryu.writeshortest(Float32(1.23456)) + @test "1.234567" == Ryu.writeshortest(Float32(1.234567)) + @test "1.2345678" == Ryu.writeshortest(Float32(1.2345678)) @test "1.23456735e-36" == Ryu.writeshortest(Float32(1.23456735e-36)) end @@ -327,8 +327,8 @@ end # Float32 @testset "Basic" begin @test "0.0" == Ryu.writeshortest(Float16(0.0)) @test "-0.0" == Ryu.writeshortest(Float16(-0.0)) - @test "1e0" == Ryu.writeshortest(Float16(1.0)) - @test "-1e0" == Ryu.writeshortest(Float16(-1.0)) + @test "1.0" == Ryu.writeshortest(Float16(1.0)) + @test "-1.0" == Ryu.writeshortest(Float16(-1.0)) @test "NaN" == Ryu.writeshortest(Float16(NaN)) @test "Inf" == Ryu.writeshortest(Float16(Inf)) @test "-Inf" == Ryu.writeshortest(Float16(-Inf))