# This file is a part of Julia. License is MIT: https://julialang.org/license using Base.Ryu const maxMantissa = (UInt64(1) << 53) - 1 todouble(sign, exp, mant) = Core.bitcast(Float64, (UInt64(sign) << 63) | (UInt64(exp) << 52) | (UInt64(mant))) @testset "Ryu" begin @testset "Float64" begin @testset "Basic" begin @test Ryu.writeshortest(0.0) == "0.0" @test Ryu.writeshortest(-0.0) == "-0.0" @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" end @testset "SwitchToSubnormal" begin @test "2.2250738585072014e-308" == Ryu.writeshortest(2.2250738585072014e-308) end @testset "MinAndMax" begin @test "1.7976931348623157e308" == Ryu.writeshortest(Core.bitcast(Float64, 0x7fefffffffffffff)) @test "5.0e-324" == Ryu.writeshortest(Core.bitcast(Float64, Int64(1))) end @testset "LotsOfTrailingZeros" begin @test "2.9802322387695312e-8" == Ryu.writeshortest(2.98023223876953125e-8) end @testset "Regression" begin @test "-2.109808898695963e16" == Ryu.writeshortest(-2.109808898695963e16) @test "4.940656e-318" == Ryu.writeshortest(4.940656e-318) @test "1.18575755e-316" == Ryu.writeshortest(1.18575755e-316) @test "2.989102097996e-312" == Ryu.writeshortest(2.989102097996e-312) @test "9.0608011534336e15" == Ryu.writeshortest(9.0608011534336e15) @test "4.708356024711512e18" == Ryu.writeshortest(4.708356024711512e18) @test "9.409340012568248e18" == Ryu.writeshortest(9.409340012568248e18) @test "1.2345678" == Ryu.writeshortest(1.2345678) end @testset "LooksLikePow5" begin # These numbers have a mantissa that is a multiple of the largest power of 5 that fits, # and an exponent that causes the computation for q to result in 22, which is a corner # case for Ryu. @test "5.764607523034235e39" == Ryu.writeshortest(Core.bitcast(Float64, 0x4830F0CF064DD592)) @test "1.152921504606847e40" == Ryu.writeshortest(Core.bitcast(Float64, 0x4840F0CF064DD592)) @test "2.305843009213694e40" == Ryu.writeshortest(Core.bitcast(Float64, 0x4850F0CF064DD592)) end @testset "pow5 overflow (#47464)" begin @test "4.6458339e+63" == Ryu.writeexp(4.645833859177319e63, 7) @test "4.190673780e+40" == Ryu.writeexp(4.190673779576499e40, 9) end @testset "OutputLength" begin @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.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 @testset "MinMaxShift" begin # 32-bit opt-size=0: 49 <= dist <= 50 # 32-bit opt-size=1: 30 <= dist <= 50 # 64-bit opt-size=0: 50 <= dist <= 50 # 64-bit opt-size=1: 30 <= dist <= 50 @test "1.7800590868057611e-307" == Ryu.writeshortest(todouble(false, 4, 0)) # 32-bit opt-size=0: 49 <= dist <= 49 # 32-bit opt-size=1: 28 <= dist <= 49 # 64-bit opt-size=0: 50 <= dist <= 50 # 64-bit opt-size=1: 28 <= dist <= 50 @test "2.8480945388892175e-306" == Ryu.writeshortest(todouble(false, 6, maxMantissa)) # 32-bit opt-size=0: 52 <= dist <= 53 # 32-bit opt-size=1: 2 <= dist <= 53 # 64-bit opt-size=0: 53 <= dist <= 53 # 64-bit opt-size=1: 2 <= dist <= 53 @test "2.446494580089078e-296" == Ryu.writeshortest(todouble(false, 41, 0)) # 32-bit opt-size=0: 52 <= dist <= 52 # 32-bit opt-size=1: 2 <= dist <= 52 # 64-bit opt-size=0: 53 <= dist <= 53 # 64-bit opt-size=1: 2 <= dist <= 53 @test "4.8929891601781557e-296" == Ryu.writeshortest(todouble(false, 40, maxMantissa)) # 32-bit opt-size=0: 57 <= dist <= 58 # 32-bit opt-size=1: 57 <= dist <= 58 # 64-bit opt-size=0: 58 <= dist <= 58 # 64-bit opt-size=1: 58 <= dist <= 58 @test "1.8014398509481984e16" == Ryu.writeshortest(todouble(false, 1077, 0)) # 32-bit opt-size=0: 57 <= dist <= 57 # 32-bit opt-size=1: 57 <= dist <= 57 # 64-bit opt-size=0: 58 <= dist <= 58 # 64-bit opt-size=1: 58 <= dist <= 58 @test "3.6028797018963964e16" == Ryu.writeshortest(todouble(false, 1076, maxMantissa)) # 32-bit opt-size=0: 51 <= dist <= 52 # 32-bit opt-size=1: 51 <= dist <= 59 # 64-bit opt-size=0: 52 <= dist <= 52 # 64-bit opt-size=1: 52 <= dist <= 59 @test "2.900835519859558e-216" == Ryu.writeshortest(todouble(false, 307, 0)) # 32-bit opt-size=0: 51 <= dist <= 51 # 32-bit opt-size=1: 51 <= dist <= 59 # 64-bit opt-size=0: 52 <= dist <= 52 # 64-bit opt-size=1: 52 <= dist <= 59 @test "5.801671039719115e-216" == Ryu.writeshortest(todouble(false, 306, maxMantissa)) # https:#github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483 # 32-bit opt-size=0: 49 <= dist <= 49 # 32-bit opt-size=1: 44 <= dist <= 49 # 64-bit opt-size=0: 50 <= dist <= 50 # 64-bit opt-size=1: 44 <= dist <= 50 @test "3.196104012172126e-27" == Ryu.writeshortest(todouble(false, 934, 0x000FA7161A4D6E0C)) end @testset "SmallIntegers" begin @test "9.007199254740991e15" == Ryu.writeshortest(9007199254740991.0) @test "9.007199254740992e15" == Ryu.writeshortest(9007199254740992.0) @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 "123456.0" == Ryu.writeshortest(1.23456e+5) @test "1.234567e6" == Ryu.writeshortest(1.234567e+6) @test "1.2345678e7" == Ryu.writeshortest(1.2345678e+7) @test "1.23456789e8" == Ryu.writeshortest(1.23456789e+8) @test "1.23456789e9" == Ryu.writeshortest(1.23456789e+9) @test "1.234567895e9" == Ryu.writeshortest(1.234567895e+9) @test "1.2345678901e10" == Ryu.writeshortest(1.2345678901e+10) @test "1.23456789012e11" == Ryu.writeshortest(1.23456789012e+11) @test "1.234567890123e12" == Ryu.writeshortest(1.234567890123e+12) @test "1.2345678901234e13" == Ryu.writeshortest(1.2345678901234e+13) @test "1.23456789012345e14" == Ryu.writeshortest(1.23456789012345e+14) @test "1.234567890123456e15" == Ryu.writeshortest(1.234567890123456e+15) # 10^i @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 "100000.0" == Ryu.writeshortest(1.0e+5) @test "1.0e6" == Ryu.writeshortest(1.0e+6) @test "1.0e7" == Ryu.writeshortest(1.0e+7) @test "1.0e8" == Ryu.writeshortest(1.0e+8) @test "1.0e9" == Ryu.writeshortest(1.0e+9) @test "1.0e10" == Ryu.writeshortest(1.0e+10) @test "1.0e11" == Ryu.writeshortest(1.0e+11) @test "1.0e12" == Ryu.writeshortest(1.0e+12) @test "1.0e13" == Ryu.writeshortest(1.0e+13) @test "1.0e14" == Ryu.writeshortest(1.0e+14) @test "1.0e15" == Ryu.writeshortest(1.0e+15) # 10^15 + 10^i @test "1.000000000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+0) @test "1.00000000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+1) @test "1.0000000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+2) @test "1.000000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+3) @test "1.00000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+4) @test "1.0000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+5) @test "1.000000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+6) @test "1.00000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+7) @test "1.0000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+8) @test "1.000001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+9) @test "1.00001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+10) @test "1.0001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+11) @test "1.001e15" == Ryu.writeshortest(1.0e+15 + 1.0e+12) @test "1.01e15" == Ryu.writeshortest(1.0e+15 + 1.0e+13) @test "1.1e15" == Ryu.writeshortest(1.0e+15 + 1.0e+14) # Largest power of 2 <= 10^(i+1) @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 "524288.0" == Ryu.writeshortest(524288.0) @test "8.388608e6" == Ryu.writeshortest(8388608.0) @test "6.7108864e7" == Ryu.writeshortest(67108864.0) @test "5.36870912e8" == Ryu.writeshortest(536870912.0) @test "8.589934592e9" == Ryu.writeshortest(8589934592.0) @test "6.8719476736e10" == Ryu.writeshortest(68719476736.0) @test "5.49755813888e11" == Ryu.writeshortest(549755813888.0) @test "8.796093022208e12" == Ryu.writeshortest(8796093022208.0) @test "7.0368744177664e13" == Ryu.writeshortest(70368744177664.0) @test "5.62949953421312e14" == Ryu.writeshortest(562949953421312.0) @test "9.007199254740992e15" == Ryu.writeshortest(9007199254740992.0) # 1000 * (Largest power of 2 <= 10^(i+1)) @test "8000.0" == Ryu.writeshortest(8.0e+3) @test "64000.0" == Ryu.writeshortest(64.0e+3) @test "512000.0" == Ryu.writeshortest(512.0e+3) @test "8.192e6" == Ryu.writeshortest(8192.0e+3) @test "6.5536e7" == Ryu.writeshortest(65536.0e+3) @test "5.24288e8" == Ryu.writeshortest(524288.0e+3) @test "8.388608e9" == Ryu.writeshortest(8388608.0e+3) @test "6.7108864e10" == Ryu.writeshortest(67108864.0e+3) @test "5.36870912e11" == Ryu.writeshortest(536870912.0e+3) @test "8.589934592e12" == Ryu.writeshortest(8589934592.0e+3) @test "6.8719476736e13" == Ryu.writeshortest(68719476736.0e+3) @test "5.49755813888e14" == Ryu.writeshortest(549755813888.0e+3) @test "8.796093022208e15" == Ryu.writeshortest(8796093022208.0e+3) end end # Float64 @testset "Float32" begin @testset "Basic" begin @test "0.0" == Ryu.writeshortest(Float32(0.0)) @test "-0.0" == Ryu.writeshortest(Float32(-0.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)) end @testset "SwitchToSubnormal" begin @test "1.1754944e-38" == Ryu.writeshortest(1.1754944f-38) end @testset "MinAndMax" begin @test "3.4028235e38" == Ryu.writeshortest(Core.bitcast(Float32, 0x7f7fffff)) @test "1.0e-45" == Ryu.writeshortest(Core.bitcast(Float32, Int32(1))) end # Check that we return the exact boundary if it is the shortest # representation, but only if the original floating point number is even. @testset "BoundaryRoundeven" begin @test "3.355445e7" == Ryu.writeshortest(3.355445f7) @test "9.0e9" == Ryu.writeshortest(8.999999f9) @test "3.436672e10" == Ryu.writeshortest(3.4366717f10) end # If the exact value is exactly halfway between two shortest representations, # then we round to even. It seems like this only makes a difference if the # last two digits are ...2|5 or ...7|5, and we cut off the 5. @testset "exactValueRoundeven" begin @test "305404.12" == Ryu.writeshortest(3.0540412f5) @test "8099.0312" == Ryu.writeshortest(8.0990312f3) end @testset "LotsOfTrailingZeros" begin # Pattern for the first test: 00111001100000000000000000000000 @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 @test "4.7223665e21" == Ryu.writeshortest(4.7223665f21) @test "8.388608e6" == Ryu.writeshortest(8388608f0) @test "1.6777216e7" == Ryu.writeshortest(1.6777216f7) @test "3.3554436e7" == Ryu.writeshortest(3.3554436f7) @test "6.7131496e7" == Ryu.writeshortest(6.7131496f7) @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 "4103.9004" == Ryu.writeshortest(4103.9003f0) @test "5.3399997e9" == Ryu.writeshortest(5.3399997f9) @test "6.0898e-39" == Ryu.writeshortest(6.0898f-39) @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) @test "6.710887e7" == Ryu.writeshortest(6.7108872f7) @test "1.0e-44" == Ryu.writeshortest(1.0f-44) @test "2.816025e14" == Ryu.writeshortest(2.816025f14) @test "9.223372e18" == Ryu.writeshortest(9.223372f18) @test "1.5846086e29" == Ryu.writeshortest(1.5846085f29) @test "1.1811161e19" == Ryu.writeshortest(1.1811161f19) @test "5.368709e18" == Ryu.writeshortest(5.368709f18) @test "4.6143166e18" == Ryu.writeshortest(4.6143165f18) @test "0.007812537" == Ryu.writeshortest(0.007812537f0) @test "1.0e-45" == Ryu.writeshortest(1.4f-45) @test "1.18697725e20" == Ryu.writeshortest(1.18697724f20) @test "1.00014165e-36" == Ryu.writeshortest(1.00014165f-36) @test "200.0" == Ryu.writeshortest(200f0) @test "3.3554432e7" == Ryu.writeshortest(3.3554432f7) end @testset "LooksLikePow5" begin # These numbers have a mantissa that is the largest power of 5 that fits, # and an exponent that causes the computation for q to result in 10, which is a corner # case for Ryu. @test "6.7108864e17" == Ryu.writeshortest(Core.bitcast(Float32, 0x5D1502F9)) @test "1.3421773e18" == Ryu.writeshortest(Core.bitcast(Float32, 0x5D9502F9)) @test "2.6843546e18" == Ryu.writeshortest(Core.bitcast(Float32, 0x5E1502F9)) end @testset "OutputLength" begin @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 end # Float32 @testset "Float16" begin @testset "Basic" begin @test "0.0" == Ryu.writeshortest(Float16(0.0)) @test "-0.0" == Ryu.writeshortest(Float16(-0.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)) end let x=floatmin(Float16) while x <= floatmax(Float16) @test parse(Float16, Ryu.writeshortest(x)) == x x = nextfloat(x) end end # function testfloats(T) # x = floatmin(T) # i = 0 # fails = 0 # success = 0 # while x < floatmax(T) # test = parse(T, Ryu.writeshortest(x)) == x # if !test # fails += 1 # else # success += 1 # end # x = nextfloat(x) # i += 1 # end # return fails / (fails + success) # end end # Float16 @testset "Ryu.writefixed" begin @testset "Basic" begin @test Ryu.writefixed(todouble(false, 1234, 99999), 0) == "3291009114715486435425664845573426149758869524108446525879746560" end @testset "Zero" begin @test Ryu.writefixed(0.0, 4) == "0.0000" @test Ryu.writefixed(0.0, 3) == "0.000" @test Ryu.writefixed(0.0, 2) == "0.00" @test Ryu.writefixed(0.0, 1) == "0.0" @test Ryu.writefixed(0.0, 0) == "0" end @testset "MinMax" begin @test Ryu.writefixed(todouble(false, 0, 1), 1074) == "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" * "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" * "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" * "000000000000000000000000000000000000000000000000000000049406564584124654417656879286822137" * "236505980261432476442558568250067550727020875186529983636163599237979656469544571773092665" * "671035593979639877479601078187812630071319031140452784581716784898210368871863605699873072" * "305000638740915356498438731247339727316961514003171538539807412623856559117102665855668676" * "818703956031062493194527159149245532930545654440112748012970999954193198940908041656332452" * "475714786901472678015935523861155013480352649347201937902681071074917033322268447533357208" * "324319360923828934583680601060115061698097530783422773183292479049825247307763759272478746" * "560847782037344696995336470179726777175851256605511991315048911014510378627381672509558373" * "89733598993664809941164205702637090279242767544565229087538682506419718265533447265625" @test Ryu.writefixed(todouble(false, 2046, 0xFFFFFFFFFFFFF), 0) == "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558" * "632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245" * "490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168" * "738177180919299881250404026184124858368" end @testset "RoundToEven" begin @test Ryu.writefixed(0.125, 3) == "0.125" @test Ryu.writefixed(0.125, 2) == "0.12" @test Ryu.writefixed(0.375, 3) == "0.375" @test Ryu.writefixed(0.375, 2) == "0.38" end @testset "RoundToEvenInteger" begin @test Ryu.writefixed(2.5, 1) == "2.5" @test Ryu.writefixed(2.5, 0) == "2" @test Ryu.writefixed(3.5, 1) == "3.5" @test Ryu.writefixed(3.5, 0) == "4" end @testset "NonRoundToEvenScenarios" begin @test Ryu.writefixed(0.748046875, 3) == "0.748" @test Ryu.writefixed(0.748046875, 2) == "0.75" @test Ryu.writefixed(0.748046875, 1) == "0.7" @test Ryu.writefixed(0.2509765625, 3) == "0.251" @test Ryu.writefixed(0.2509765625, 2) == "0.25" @test Ryu.writefixed(0.2509765625, 1) == "0.3" @test Ryu.writefixed(todouble(false, 1021, 1), 54) == "0.250000000000000055511151231257827021181583404541015625" @test Ryu.writefixed(todouble(false, 1021, 1), 3) == "0.250" @test Ryu.writefixed(todouble(false, 1021, 1), 2) == "0.25" @test Ryu.writefixed(todouble(false, 1021, 1), 1) == "0.3" end @testset "VaryingPrecision" begin @test Ryu.writefixed(1729.142857142857, 47) == "1729.14285714285711037518922239542007446289062500000" @test Ryu.writefixed(1729.142857142857, 46) == "1729.1428571428571103751892223954200744628906250000" @test Ryu.writefixed(1729.142857142857, 45) == "1729.142857142857110375189222395420074462890625000" @test Ryu.writefixed(1729.142857142857, 44) == "1729.14285714285711037518922239542007446289062500" @test Ryu.writefixed(1729.142857142857, 43) == "1729.1428571428571103751892223954200744628906250" @test Ryu.writefixed(1729.142857142857, 42) == "1729.142857142857110375189222395420074462890625" @test Ryu.writefixed(1729.142857142857, 41) == "1729.14285714285711037518922239542007446289062" @test Ryu.writefixed(1729.142857142857, 40) == "1729.1428571428571103751892223954200744628906" @test Ryu.writefixed(1729.142857142857, 39) == "1729.142857142857110375189222395420074462891" @test Ryu.writefixed(1729.142857142857, 38) == "1729.14285714285711037518922239542007446289" @test Ryu.writefixed(1729.142857142857, 37) == "1729.1428571428571103751892223954200744629" @test Ryu.writefixed(1729.142857142857, 36) == "1729.142857142857110375189222395420074463" @test Ryu.writefixed(1729.142857142857, 35) == "1729.14285714285711037518922239542007446" @test Ryu.writefixed(1729.142857142857, 34) == "1729.1428571428571103751892223954200745" @test Ryu.writefixed(1729.142857142857, 33) == "1729.142857142857110375189222395420074" @test Ryu.writefixed(1729.142857142857, 32) == "1729.14285714285711037518922239542007" @test Ryu.writefixed(1729.142857142857, 31) == "1729.1428571428571103751892223954201" @test Ryu.writefixed(1729.142857142857, 30) == "1729.142857142857110375189222395420" @test Ryu.writefixed(1729.142857142857, 29) == "1729.14285714285711037518922239542" @test Ryu.writefixed(1729.142857142857, 28) == "1729.1428571428571103751892223954" @test Ryu.writefixed(1729.142857142857, 27) == "1729.142857142857110375189222395" @test Ryu.writefixed(1729.142857142857, 26) == "1729.14285714285711037518922240" @test Ryu.writefixed(1729.142857142857, 25) == "1729.1428571428571103751892224" @test Ryu.writefixed(1729.142857142857, 24) == "1729.142857142857110375189222" @test Ryu.writefixed(1729.142857142857, 23) == "1729.14285714285711037518922" @test Ryu.writefixed(1729.142857142857, 22) == "1729.1428571428571103751892" @test Ryu.writefixed(1729.142857142857, 21) == "1729.142857142857110375189" @test Ryu.writefixed(1729.142857142857, 20) == "1729.14285714285711037519" @test Ryu.writefixed(1729.142857142857, 19) == "1729.1428571428571103752" @test Ryu.writefixed(1729.142857142857, 18) == "1729.142857142857110375" @test Ryu.writefixed(1729.142857142857, 17) == "1729.14285714285711038" @test Ryu.writefixed(1729.142857142857, 16) == "1729.1428571428571104" @test Ryu.writefixed(1729.142857142857, 15) == "1729.142857142857110" @test Ryu.writefixed(1729.142857142857, 14) == "1729.14285714285711" @test Ryu.writefixed(1729.142857142857, 13) == "1729.1428571428571" @test Ryu.writefixed(1729.142857142857, 12) == "1729.142857142857" @test Ryu.writefixed(1729.142857142857, 11) == "1729.14285714286" @test Ryu.writefixed(1729.142857142857, 10) == "1729.1428571429" @test Ryu.writefixed(1729.142857142857, 9) == "1729.142857143" @test Ryu.writefixed(1729.142857142857, 8) == "1729.14285714" @test Ryu.writefixed(1729.142857142857, 7) == "1729.1428571" @test Ryu.writefixed(1729.142857142857, 6) == "1729.142857" @test Ryu.writefixed(1729.142857142857, 5) == "1729.14286" @test Ryu.writefixed(1729.142857142857, 4) == "1729.1429" @test Ryu.writefixed(1729.142857142857, 3) == "1729.143" @test Ryu.writefixed(1729.142857142857, 2) == "1729.14" @test Ryu.writefixed(1729.142857142857, 1) == "1729.1" @test Ryu.writefixed(1729.142857142857, 0) == "1729" end @testset "Carrying" begin @test Ryu.writefixed( 0.0009, 4) == "0.0009" @test Ryu.writefixed( 0.0009, 3) == "0.001" @test Ryu.writefixed( 0.0029, 4) == "0.0029" @test Ryu.writefixed( 0.0029, 3) == "0.003" @test Ryu.writefixed( 0.0099, 4) == "0.0099" @test Ryu.writefixed( 0.0099, 3) == "0.010" @test Ryu.writefixed( 0.0299, 4) == "0.0299" @test Ryu.writefixed( 0.0299, 3) == "0.030" @test Ryu.writefixed( 0.0999, 4) == "0.0999" @test Ryu.writefixed( 0.0999, 3) == "0.100" @test Ryu.writefixed( 0.2999, 4) == "0.2999" @test Ryu.writefixed( 0.2999, 3) == "0.300" @test Ryu.writefixed( 0.9999, 4) == "0.9999" @test Ryu.writefixed( 0.9999, 3) == "1.000" @test Ryu.writefixed( 2.9999, 4) == "2.9999" @test Ryu.writefixed( 2.9999, 3) == "3.000" @test Ryu.writefixed( 9.9999, 4) == "9.9999" @test Ryu.writefixed( 9.9999, 3) == "10.000" @test Ryu.writefixed( 29.9999, 4) == "29.9999" @test Ryu.writefixed( 29.9999, 3) == "30.000" @test Ryu.writefixed( 99.9999, 4) == "99.9999" @test Ryu.writefixed( 99.9999, 3) == "100.000" @test Ryu.writefixed(299.9999, 4) == "299.9999" @test Ryu.writefixed(299.9999, 3) == "300.000" @test Ryu.writefixed( 0.09, 2) == "0.09" @test Ryu.writefixed( 0.09, 1) == "0.1" @test Ryu.writefixed( 0.29, 2) == "0.29" @test Ryu.writefixed( 0.29, 1) == "0.3" @test Ryu.writefixed( 0.99, 2) == "0.99" @test Ryu.writefixed( 0.99, 1) == "1.0" @test Ryu.writefixed( 2.99, 2) == "2.99" @test Ryu.writefixed( 2.99, 1) == "3.0" @test Ryu.writefixed( 9.99, 2) == "9.99" @test Ryu.writefixed( 9.99, 1) == "10.0" @test Ryu.writefixed( 29.99, 2) == "29.99" @test Ryu.writefixed( 29.99, 1) == "30.0" @test Ryu.writefixed( 99.99, 2) == "99.99" @test Ryu.writefixed( 99.99, 1) == "100.0" @test Ryu.writefixed(299.99, 2) == "299.99" @test Ryu.writefixed(299.99, 1) == "300.0" @test Ryu.writefixed( 0.9, 1) == "0.9" @test Ryu.writefixed( 0.9, 0) == "1" @test Ryu.writefixed( 2.9, 1) == "2.9" @test Ryu.writefixed( 2.9, 0) == "3" @test Ryu.writefixed( 9.9, 1) == "9.9" @test Ryu.writefixed( 9.9, 0) == "10" @test Ryu.writefixed( 29.9, 1) == "29.9" @test Ryu.writefixed( 29.9, 0) == "30" @test Ryu.writefixed( 99.9, 1) == "99.9" @test Ryu.writefixed( 99.9, 0) == "100" @test Ryu.writefixed(299.9, 1) == "299.9" @test Ryu.writefixed(299.9, 0) == "300" end @testset "RoundingResultZero" begin @test Ryu.writefixed(0.004, 3) == "0.004" @test Ryu.writefixed(0.004, 2) == "0.00" @test Ryu.writefixed(0.4, 1) == "0.4" @test Ryu.writefixed(0.4, 0) == "0" @test Ryu.writefixed(0.5, 1) == "0.5" @test Ryu.writefixed(0.5, 0) == "0" end @testset "Regression" begin @test Ryu.writefixed(7.018232e-82, 6) == "0.000000" end @testset "Trimming of trailing zeros" begin @test Ryu.writefixed(0.0, 1, false, false, false, UInt8('.'), true) == "0" @test Ryu.writefixed(1.0, 1, false, false, false, UInt8('.'), true) == "1" @test Ryu.writefixed(2.0, 1, false, false, false, UInt8('.'), true) == "2" @test Ryu.writefixed(1.25e+5, 0, false, false, false, UInt8('.'), true) == "125000" @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 @testset "Basic" begin @test Ryu.writeexp(todouble(false, 1234, 99999), 62) == "3.29100911471548643542566484557342614975886952410844652587974656e+63" end @testset "Zero" begin @test Ryu.writeexp(0.0, 4) == "0.0000e+00" @test Ryu.writeexp(0.0, 3) == "0.000e+00" @test Ryu.writeexp(0.0, 2) == "0.00e+00" @test Ryu.writeexp(0.0, 1) == "0.0e+00" @test Ryu.writeexp(0.0, 0) == "0e+00" end @testset "MinMax" begin @test Ryu.writeexp(todouble(false, 0, 1), 750) == "4.9406564584124654417656879286822137236505980261432476442558568250067550727020875186529983" * "636163599237979656469544571773092665671035593979639877479601078187812630071319031140452784" * "581716784898210368871863605699873072305000638740915356498438731247339727316961514003171538" * "539807412623856559117102665855668676818703956031062493194527159149245532930545654440112748" * "012970999954193198940908041656332452475714786901472678015935523861155013480352649347201937" * "902681071074917033322268447533357208324319360923828934583680601060115061698097530783422773" * "183292479049825247307763759272478746560847782037344696995336470179726777175851256605511991" * "315048911014510378627381672509558373897335989936648099411642057026370902792427675445652290" * "87538682506419718265533447265625e-324" @test Ryu.writeexp(todouble(false, 2046, 0xFFFFFFFFFFFFF), 308) == "1.7976931348623157081452742373170435679807056752584499659891747680315726078002853876058955" * "863276687817154045895351438246423432132688946418276846754670353751698604991057655128207624" * "549009038932894407586850845513394230458323690322294816580855933212334827479782620414472316" * "8738177180919299881250404026184124858368e+308" end @testset "RoundToEven" begin @test Ryu.writeexp(0.125, 2) == "1.25e-01" @test Ryu.writeexp(0.125, 1) == "1.2e-01" @test Ryu.writeexp(0.375, 2) == "3.75e-01" @test Ryu.writeexp(0.375, 1) == "3.8e-01" end @testset "RoundToEvenInteger" begin @test Ryu.writeexp(2.5, 1) == "2.5e+00" @test Ryu.writeexp(2.5, 0) == "2e+00" @test Ryu.writeexp(3.5, 1) == "3.5e+00" @test Ryu.writeexp(3.5, 0) == "4e+00" end @testset "NonRoundToEvenScenarios" begin @test Ryu.writeexp(0.748046875, 2) == "7.48e-01" @test Ryu.writeexp(0.748046875, 1) == "7.5e-01" @test Ryu.writeexp(0.748046875, 0) == "7e-01" # 0.75 would round to "8e-01", but this is smaller @test Ryu.writeexp(0.2509765625, 2) == "2.51e-01" @test Ryu.writeexp(0.2509765625, 1) == "2.5e-01" @test Ryu.writeexp(0.2509765625, 0) == "3e-01" # 0.25 would round to "2e-01", but this is larger @test Ryu.writeexp(todouble(false, 1021, 1), 53) == "2.50000000000000055511151231257827021181583404541015625e-01" @test Ryu.writeexp(todouble(false, 1021, 1), 2) == "2.50e-01" @test Ryu.writeexp(todouble(false, 1021, 1), 1) == "2.5e-01" @test Ryu.writeexp(todouble(false, 1021, 1), 0) == "3e-01" # 0.25 would round to "2e-01", but this is larger (again) end @testset "VaryingPrecision" begin @test Ryu.writeexp(1729.142857142857, 50) == "1.72914285714285711037518922239542007446289062500000e+03" @test Ryu.writeexp(1729.142857142857, 49) == "1.7291428571428571103751892223954200744628906250000e+03" @test Ryu.writeexp(1729.142857142857, 48) == "1.729142857142857110375189222395420074462890625000e+03" @test Ryu.writeexp(1729.142857142857, 47) == "1.72914285714285711037518922239542007446289062500e+03" @test Ryu.writeexp(1729.142857142857, 46) == "1.7291428571428571103751892223954200744628906250e+03" @test Ryu.writeexp(1729.142857142857, 45) == "1.729142857142857110375189222395420074462890625e+03" @test Ryu.writeexp(1729.142857142857, 44) == "1.72914285714285711037518922239542007446289062e+03" @test Ryu.writeexp(1729.142857142857, 43) == "1.7291428571428571103751892223954200744628906e+03" @test Ryu.writeexp(1729.142857142857, 42) == "1.729142857142857110375189222395420074462891e+03" @test Ryu.writeexp(1729.142857142857, 41) == "1.72914285714285711037518922239542007446289e+03" @test Ryu.writeexp(1729.142857142857, 40) == "1.7291428571428571103751892223954200744629e+03" @test Ryu.writeexp(1729.142857142857, 39) == "1.729142857142857110375189222395420074463e+03" @test Ryu.writeexp(1729.142857142857, 38) == "1.72914285714285711037518922239542007446e+03" @test Ryu.writeexp(1729.142857142857, 37) == "1.7291428571428571103751892223954200745e+03" @test Ryu.writeexp(1729.142857142857, 36) == "1.729142857142857110375189222395420074e+03" @test Ryu.writeexp(1729.142857142857, 35) == "1.72914285714285711037518922239542007e+03" @test Ryu.writeexp(1729.142857142857, 34) == "1.7291428571428571103751892223954201e+03" @test Ryu.writeexp(1729.142857142857, 33) == "1.729142857142857110375189222395420e+03" @test Ryu.writeexp(1729.142857142857, 32) == "1.72914285714285711037518922239542e+03" @test Ryu.writeexp(1729.142857142857, 31) == "1.7291428571428571103751892223954e+03" @test Ryu.writeexp(1729.142857142857, 30) == "1.729142857142857110375189222395e+03" @test Ryu.writeexp(1729.142857142857, 29) == "1.72914285714285711037518922240e+03" @test Ryu.writeexp(1729.142857142857, 28) == "1.7291428571428571103751892224e+03" @test Ryu.writeexp(1729.142857142857, 27) == "1.729142857142857110375189222e+03" @test Ryu.writeexp(1729.142857142857, 26) == "1.72914285714285711037518922e+03" @test Ryu.writeexp(1729.142857142857, 25) == "1.7291428571428571103751892e+03" @test Ryu.writeexp(1729.142857142857, 24) == "1.729142857142857110375189e+03" @test Ryu.writeexp(1729.142857142857, 23) == "1.72914285714285711037519e+03" @test Ryu.writeexp(1729.142857142857, 22) == "1.7291428571428571103752e+03" @test Ryu.writeexp(1729.142857142857, 21) == "1.729142857142857110375e+03" @test Ryu.writeexp(1729.142857142857, 20) == "1.72914285714285711038e+03" @test Ryu.writeexp(1729.142857142857, 19) == "1.7291428571428571104e+03" @test Ryu.writeexp(1729.142857142857, 18) == "1.729142857142857110e+03" @test Ryu.writeexp(1729.142857142857, 17) == "1.72914285714285711e+03" @test Ryu.writeexp(1729.142857142857, 16) == "1.7291428571428571e+03" @test Ryu.writeexp(1729.142857142857, 15) == "1.729142857142857e+03" @test Ryu.writeexp(1729.142857142857, 14) == "1.72914285714286e+03" @test Ryu.writeexp(1729.142857142857, 13) == "1.7291428571429e+03" @test Ryu.writeexp(1729.142857142857, 12) == "1.729142857143e+03" @test Ryu.writeexp(1729.142857142857, 11) == "1.72914285714e+03" @test Ryu.writeexp(1729.142857142857, 10) == "1.7291428571e+03" @test Ryu.writeexp(1729.142857142857, 9) == "1.729142857e+03" @test Ryu.writeexp(1729.142857142857, 8) == "1.72914286e+03" @test Ryu.writeexp(1729.142857142857, 7) == "1.7291429e+03" @test Ryu.writeexp(1729.142857142857, 6) == "1.729143e+03" @test Ryu.writeexp(1729.142857142857, 5) == "1.72914e+03" @test Ryu.writeexp(1729.142857142857, 4) == "1.7291e+03" @test Ryu.writeexp(1729.142857142857, 3) == "1.729e+03" @test Ryu.writeexp(1729.142857142857, 2) == "1.73e+03" @test Ryu.writeexp(1729.142857142857, 1) == "1.7e+03" @test Ryu.writeexp(1729.142857142857, 0) == "2e+03" end @testset "Carrying" begin @test Ryu.writeexp(2.0009, 4) == "2.0009e+00" @test Ryu.writeexp(2.0009, 3) == "2.001e+00" @test Ryu.writeexp(2.0029, 4) == "2.0029e+00" @test Ryu.writeexp(2.0029, 3) == "2.003e+00" @test Ryu.writeexp(2.0099, 4) == "2.0099e+00" @test Ryu.writeexp(2.0099, 3) == "2.010e+00" @test Ryu.writeexp(2.0299, 4) == "2.0299e+00" @test Ryu.writeexp(2.0299, 3) == "2.030e+00" @test Ryu.writeexp(2.0999, 4) == "2.0999e+00" @test Ryu.writeexp(2.0999, 3) == "2.100e+00" @test Ryu.writeexp(2.2999, 4) == "2.2999e+00" @test Ryu.writeexp(2.2999, 3) == "2.300e+00" @test Ryu.writeexp(2.9999, 4) == "2.9999e+00" @test Ryu.writeexp(2.9999, 3) == "3.000e+00" @test Ryu.writeexp(9.9999, 4) == "9.9999e+00" @test Ryu.writeexp(9.9999, 3) == "1.000e+01" @test Ryu.writeexp(2.09, 2) == "2.09e+00" @test Ryu.writeexp(2.09, 1) == "2.1e+00" @test Ryu.writeexp(2.29, 2) == "2.29e+00" @test Ryu.writeexp(2.29, 1) == "2.3e+00" @test Ryu.writeexp(2.99, 2) == "2.99e+00" @test Ryu.writeexp(2.99, 1) == "3.0e+00" @test Ryu.writeexp(9.99, 2) == "9.99e+00" @test Ryu.writeexp(9.99, 1) == "1.0e+01" @test Ryu.writeexp(2.9, 1) == "2.9e+00" @test Ryu.writeexp(2.9, 0) == "3e+00" @test Ryu.writeexp(9.9, 1) == "9.9e+00" @test Ryu.writeexp(9.9, 0) == "1e+01" end @testset "Exponents" begin @test Ryu.writeexp(9.99e-100, 2) == "9.99e-100" @test Ryu.writeexp(9.99e-99 , 2) == "9.99e-99" @test Ryu.writeexp(9.99e-10 , 2) == "9.99e-10" @test Ryu.writeexp(9.99e-09 , 2) == "9.99e-09" @test Ryu.writeexp(9.99e-01 , 2) == "9.99e-01" @test Ryu.writeexp(9.99e+00 , 2) == "9.99e+00" @test Ryu.writeexp(9.99e+01 , 2) == "9.99e+01" @test Ryu.writeexp(9.99e+09 , 2) == "9.99e+09" @test Ryu.writeexp(9.99e+10 , 2) == "9.99e+10" @test Ryu.writeexp(9.99e+99 , 2) == "9.99e+99" @test Ryu.writeexp(9.99e+100, 2) == "9.99e+100" @test Ryu.writeexp(9.99e-100, 1) == "1.0e-99" @test Ryu.writeexp(9.99e-99 , 1) == "1.0e-98" @test Ryu.writeexp(9.99e-10 , 1) == "1.0e-09" @test Ryu.writeexp(9.99e-09 , 1) == "1.0e-08" @test Ryu.writeexp(9.99e-01 , 1) == "1.0e+00" @test Ryu.writeexp(9.99e+00 , 1) == "1.0e+01" @test Ryu.writeexp(9.99e+01 , 1) == "1.0e+02" @test Ryu.writeexp(9.99e+09 , 1) == "1.0e+10" @test Ryu.writeexp(9.99e+10 , 1) == "1.0e+11" @test Ryu.writeexp(9.99e+99 , 1) == "1.0e+100" @test Ryu.writeexp(9.99e+100, 1) == "1.0e+101" end @testset "PrintDecimalPoint" begin # These values exercise each codepath. @test Ryu.writeexp(1e+54, 0) == "1e+54" @test Ryu.writeexp(1e+54, 1) == "1.0e+54" @test Ryu.writeexp(1e-63, 0) == "1e-63" @test Ryu.writeexp(1e-63, 1) == "1.0e-63" @test Ryu.writeexp(1e+83, 0) == "1e+83" @test Ryu.writeexp(1e+83, 1) == "1.0e+83" end @testset "Consistency of trimtrailingzeros" begin @test Ryu.writeexp(0.0, 1, false, false, false, UInt8('e'), UInt8('.'), true) == "0e+00" @test Ryu.writeexp(1.0, 1, false, false, false, UInt8('e'), UInt8('.'), true) == "1e+00" @test Ryu.writeexp(2.0, 1, false, false, false, UInt8('e'), UInt8('.'), true) == "2e+00" end end # exp @testset "compact" begin stringcompact(x) = sprint(show, x; context=:compact => true) @test stringcompact(0.49999999) == "0.5" @test stringcompact(0.459999999) == "0.46" @test stringcompact(0.20058603493384108) == "0.200586" @test stringcompact(0.9999999) == "1.0" @test stringcompact(0.1999999) == "0.2" @test stringcompact(123.4567) == "123.457" @test stringcompact(0.001234567) == "0.00123457" @test stringcompact(0.1234567) == "0.123457" @test stringcompact(1234567.0) == "1.23457e6" @test stringcompact(12345678910.0) == "1.23457e10" @test stringcompact(12345678.0) == "1.23457e7" @test stringcompact(0.10000049) == "0.1" @test stringcompact(22.89825) == "22.8983" @test stringcompact(0.646690981531646) == "0.646691" @test stringcompact(6.938893903907228e-17) == "6.93889e-17" @test stringcompact(1.015625) == "1.01562" @test stringcompact(1.046875) == "1.04688" @test stringcompact(0.025621074) == "0.0256211" # subnormals @test stringcompact(eps(0.0)) == "5.0e-324" @test stringcompact(eps(0f0)) == "1.0f-45" @test stringcompact(eps(Float16(0.0))) == "6.0e-8" end end # Ryu