github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/decode_float_test.go (about) 1 //go:build amd64 && go1.16 && !go1.22 2 // +build amd64,go1.16,!go1.22 3 4 /* 5 * Copyright 2021 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package sonic 21 22 import ( 23 "encoding/json" 24 "reflect" 25 "strings" 26 "testing" 27 28 "github.com/goshafaq/sonic/decoder" 29 ) 30 31 type atofTest struct { 32 in string 33 out string 34 err error 35 } 36 37 // Tests from Go strconv package, https://github.com/golang/go/blob/master/src/strconv/atof_test.go 38 // All tests are passed in Go encoding/json. 39 var atoftests = []atofTest{ 40 {"1.234e", "", nil}, // error 41 {"1i", "1", nil}, // pass 42 {"1", "1", nil}, 43 {"1e23", "1e+23", nil}, 44 {"1E23", "1e+23", nil}, 45 {"100000000000000000000000", "1e+23", nil}, 46 {"1e-100", "1e-100", nil}, 47 {"123456700", "1.234567e+08", nil}, 48 {"99999999999999974834176", "9.999999999999997e+22", nil}, 49 {"100000000000000000000001", "1.0000000000000001e+23", nil}, 50 {"100000000000000008388608", "1.0000000000000001e+23", nil}, 51 {"100000000000000016777215", "1.0000000000000001e+23", nil}, 52 {"100000000000000016777216", "1.0000000000000003e+23", nil}, 53 {"-1", "-1", nil}, 54 {"-0.1", "-0.1", nil}, 55 {"-0", "-0", nil}, 56 {"1e-20", "1e-20", nil}, 57 {"625e-3", "0.625", nil}, 58 59 // zeros 60 {"0", "0", nil}, 61 {"0e0", "0", nil}, 62 {"-0e0", "-0", nil}, 63 {"0e-0", "0", nil}, 64 {"-0e-0", "-0", nil}, 65 {"0e+0", "0", nil}, 66 {"-0e+0", "-0", nil}, 67 {"0e+01234567890123456789", "0", nil}, 68 {"0.00e-01234567890123456789", "0", nil}, 69 {"-0e+01234567890123456789", "-0", nil}, 70 {"-0.00e-01234567890123456789", "-0", nil}, 71 72 {"0e291", "0", nil}, // issue 15364 73 {"0e292", "0", nil}, // issue 15364 74 {"0e347", "0", nil}, // issue 15364 75 {"0e348", "0", nil}, // issue 15364 76 {"-0e291", "-0", nil}, 77 {"-0e292", "-0", nil}, 78 {"-0e347", "-0", nil}, 79 {"-0e348", "-0", nil}, 80 81 // largest float64 82 {"1.7976931348623157e308", "1.7976931348623157e+308", nil}, 83 {"-1.7976931348623157e308", "-1.7976931348623157e+308", nil}, 84 85 // the border is ...158079 86 // borderline - okay 87 {"1.7976931348623158e308", "1.7976931348623157e+308", nil}, 88 {"-1.7976931348623158e308", "-1.7976931348623157e+308", nil}, 89 90 // a little too large 91 {"1e308", "1e+308", nil}, 92 93 // denormalized 94 {"1e-305", "1e-305", nil}, 95 {"1e-306", "1e-306", nil}, 96 {"1e-307", "1e-307", nil}, 97 {"1e-308", "1e-308", nil}, 98 {"1e-309", "1e-309", nil}, 99 {"1e-310", "1e-310", nil}, 100 {"1e-322", "1e-322", nil}, 101 // smallest denormal 102 {"5e-324", "5e-324", nil}, 103 {"4e-324", "5e-324", nil}, 104 {"3e-324", "5e-324", nil}, 105 // too small 106 {"2e-324", "0", nil}, 107 // way too small 108 {"1e-350", "0", nil}, 109 {"1e-400000", "0", nil}, 110 111 // try to overflow exponent 112 {"1e-4294967296", "0", nil}, 113 {"1e-18446744073709551616", "0", nil}, 114 115 // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ 116 {"2.2250738585072012e-308", "2.2250738585072014e-308", nil}, 117 // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ 118 {"2.2250738585072011e-308", "2.225073858507201e-308", nil}, 119 120 // A very large number (initially wrongly parsed by the fast algorithm). 121 {"4.630813248087435e+307", "4.630813248087435e+307", nil}, 122 123 // A different kind of very large number. 124 {"22.222222222222222", "22.22222222222222", nil}, 125 {"2." + strings.Repeat("2", 800) + "e+1", "22.22222222222222", nil}, 126 127 // Exactly halfway between 1 and math.Nextafter(1, 2). 128 // Round to even (down). 129 {"1.00000000000000011102230246251565404236316680908203125", "1", nil}, 130 // Slightly lower; still round down. 131 {"1.00000000000000011102230246251565404236316680908203124", "1", nil}, 132 // Slightly higher; round up. 133 {"1.00000000000000011102230246251565404236316680908203126", "1.0000000000000002", nil}, 134 // Slightly higher, but you have to read all the way to the end. 135 {"1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1", "1.0000000000000002", nil}, 136 137 // Halfway between x := math.Nextafter(1, 2) and math.Nextafter(x, 2) 138 // Round to even (up). 139 {"1.00000000000000033306690738754696212708950042724609375", "1.0000000000000004", nil}, 140 141 // Halfway between 1090544144181609278303144771584 and 1090544144181609419040633126912 142 // (15497564393479157p+46, should round to even 15497564393479156p+46, issue 36657) 143 {"1090544144181609348671888949248", "1.0905441441816093e+30", nil}, 144 145 // Corner case between int64 and float64 for the input 146 {"9223372036854775807", "9223372036854775807", nil}, // max int64: (1 << 63) - 1 147 {"9223372036854775808", "9223372036854775808", nil}, 148 {"-9223372036854775808", "-9223372036854775808", nil}, // min int64: 1 << 63 149 {"-9223372036854775809", "-9223372036854775809", nil}, 150 } 151 152 func TestDecodeFloat(t *testing.T) { 153 for i, tt := range atoftests { 154 // default float64 155 var sonicout, stdout float64 156 sonicerr := decoder.NewDecoder(tt.in).Decode(&sonicout) 157 stderr := json.NewDecoder(strings.NewReader(tt.in)).Decode(&stdout) 158 if !reflect.DeepEqual(sonicout, stdout) { 159 t.Fatalf("Test %d, %#v\ngot:\n %#v\nexp:\n %#v\n", i, tt.in, sonicout, stdout) 160 } 161 if !reflect.DeepEqual(sonicerr == nil, stderr == nil) { 162 t.Fatalf("Test %d, %#v\ngot:\n %#v\nexp:\n %#v\n", i, tt.in, sonicerr, stderr) 163 } 164 } 165 }