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  }