...

Source file src/strconv/atoc_test.go

Documentation: strconv

		 1  // Copyright 2020 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package strconv_test
		 6  
		 7  import (
		 8  	"math"
		 9  	"math/cmplx"
		10  	"reflect"
		11  	. "strconv"
		12  	"testing"
		13  )
		14  
		15  var (
		16  	infp0 = complex(math.Inf(+1), 0)
		17  	infm0 = complex(math.Inf(-1), 0)
		18  	inf0p = complex(0, math.Inf(+1))
		19  	inf0m = complex(0, math.Inf(-1))
		20  
		21  	infpp = complex(math.Inf(+1), math.Inf(+1))
		22  	infpm = complex(math.Inf(+1), math.Inf(-1))
		23  	infmp = complex(math.Inf(-1), math.Inf(+1))
		24  	infmm = complex(math.Inf(-1), math.Inf(-1))
		25  )
		26  
		27  type atocTest struct {
		28  	in	string
		29  	out complex128
		30  	err error
		31  }
		32  
		33  func TestParseComplex(t *testing.T) {
		34  	tests := []atocTest{
		35  		// Clearly invalid
		36  		{"", 0, ErrSyntax},
		37  		{" ", 0, ErrSyntax},
		38  		{"(", 0, ErrSyntax},
		39  		{")", 0, ErrSyntax},
		40  		{"i", 0, ErrSyntax},
		41  		{"+i", 0, ErrSyntax},
		42  		{"-i", 0, ErrSyntax},
		43  		{"1I", 0, ErrSyntax},
		44  		{"10	+ 5i", 0, ErrSyntax},
		45  		{"3+", 0, ErrSyntax},
		46  		{"3+5", 0, ErrSyntax},
		47  		{"3+5+5i", 0, ErrSyntax},
		48  
		49  		// Parentheses
		50  		{"()", 0, ErrSyntax},
		51  		{"(i)", 0, ErrSyntax},
		52  		{"(0)", 0, nil},
		53  		{"(1i)", 1i, nil},
		54  		{"(3.0+5.5i)", 3.0 + 5.5i, nil},
		55  		{"(1)+1i", 0, ErrSyntax},
		56  		{"(3.0+5.5i", 0, ErrSyntax},
		57  		{"3.0+5.5i)", 0, ErrSyntax},
		58  
		59  		// NaNs
		60  		{"NaN", complex(math.NaN(), 0), nil},
		61  		{"NANi", complex(0, math.NaN()), nil},
		62  		{"nan+nAni", complex(math.NaN(), math.NaN()), nil},
		63  		{"+NaN", 0, ErrSyntax},
		64  		{"-NaN", 0, ErrSyntax},
		65  		{"NaN-NaNi", 0, ErrSyntax},
		66  
		67  		// Infs
		68  		{"Inf", infp0, nil},
		69  		{"+inf", infp0, nil},
		70  		{"-inf", infm0, nil},
		71  		{"Infinity", infp0, nil},
		72  		{"+INFINITY", infp0, nil},
		73  		{"-infinity", infm0, nil},
		74  		{"+infi", inf0p, nil},
		75  		{"0-infinityi", inf0m, nil},
		76  		{"Inf+Infi", infpp, nil},
		77  		{"+Inf-Infi", infpm, nil},
		78  		{"-Infinity+Infi", infmp, nil},
		79  		{"inf-inf", 0, ErrSyntax},
		80  
		81  		// Zeros
		82  		{"0", 0, nil},
		83  		{"0i", 0, nil},
		84  		{"-0.0i", 0, nil},
		85  		{"0+0.0i", 0, nil},
		86  		{"0e+0i", 0, nil},
		87  		{"0e-0+0i", 0, nil},
		88  		{"-0.0-0.0i", 0, nil},
		89  		{"0e+012345", 0, nil},
		90  		{"0x0p+012345i", 0, nil},
		91  		{"0x0.00p-012345i", 0, nil},
		92  		{"+0e-0+0e-0i", 0, nil},
		93  		{"0e+0+0e+0i", 0, nil},
		94  		{"-0e+0-0e+0i", 0, nil},
		95  
		96  		// Regular non-zeroes
		97  		{"0.1", 0.1, nil},
		98  		{"0.1i", 0 + 0.1i, nil},
		99  		{"0.123", 0.123, nil},
	 100  		{"0.123i", 0 + 0.123i, nil},
	 101  		{"0.123+0.123i", 0.123 + 0.123i, nil},
	 102  		{"99", 99, nil},
	 103  		{"+99", 99, nil},
	 104  		{"-99", -99, nil},
	 105  		{"+1i", 1i, nil},
	 106  		{"-1i", -1i, nil},
	 107  		{"+3+1i", 3 + 1i, nil},
	 108  		{"30+3i", 30 + 3i, nil},
	 109  		{"+3e+3-3e+3i", 3e+3 - 3e+3i, nil},
	 110  		{"+3e+3+3e+3i", 3e+3 + 3e+3i, nil},
	 111  		{"+3e+3+3e+3i+", 0, ErrSyntax},
	 112  
	 113  		// Separators
	 114  		{"0.1", 0.1, nil},
	 115  		{"0.1i", 0 + 0.1i, nil},
	 116  		{"0.1_2_3", 0.123, nil},
	 117  		{"+0x_3p3i", 0x3p3i, nil},
	 118  		{"0_0+0x_0p0i", 0, nil},
	 119  		{"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
	 120  		{"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil},
	 121  		{"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil},
	 122  
	 123  		// Hexadecimals
	 124  		{"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
	 125  		{"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
	 126  		{"0x10.3p+8-0x3p3i", 0x10.3p+8 - 0x3p3i, nil},
	 127  		{"0x1p0", 1, nil},
	 128  		{"0x1p1", 2, nil},
	 129  		{"0x1p-1", 0.5, nil},
	 130  		{"0x1ep-1", 15, nil},
	 131  		{"-0x1ep-1", -15, nil},
	 132  		{"-0x2p3", -16, nil},
	 133  		{"0x1e2", 0, ErrSyntax},
	 134  		{"1p2", 0, ErrSyntax},
	 135  		{"0x1e2i", 0, ErrSyntax},
	 136  
	 137  		// ErrRange
	 138  		// next float64 - too large
	 139  		{"+0x1p1024", infp0, ErrRange},
	 140  		{"-0x1p1024", infm0, ErrRange},
	 141  		{"+0x1p1024i", inf0p, ErrRange},
	 142  		{"-0x1p1024i", inf0m, ErrRange},
	 143  		{"+0x1p1024+0x1p1024i", infpp, ErrRange},
	 144  		{"+0x1p1024-0x1p1024i", infpm, ErrRange},
	 145  		{"-0x1p1024+0x1p1024i", infmp, ErrRange},
	 146  		{"-0x1p1024-0x1p1024i", infmm, ErrRange},
	 147  		// the border is ...158079
	 148  		// borderline - okay
	 149  		{"+0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
	 150  		{"+0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
	 151  		{"-0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
	 152  		{"-0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
	 153  		// borderline - too large
	 154  		{"+0x1.fffffffffffff8p1023", infp0, ErrRange},
	 155  		{"-0x1fffffffffffff.8p+971", infm0, ErrRange},
	 156  		{"+0x1.fffffffffffff8p1023i", inf0p, ErrRange},
	 157  		{"-0x1fffffffffffff.8p+971i", inf0m, ErrRange},
	 158  		{"+0x1.fffffffffffff8p1023+0x1.fffffffffffff8p1023i", infpp, ErrRange},
	 159  		{"+0x1.fffffffffffff8p1023-0x1.fffffffffffff8p1023i", infpm, ErrRange},
	 160  		{"-0x1fffffffffffff.8p+971+0x1fffffffffffff.8p+971i", infmp, ErrRange},
	 161  		{"-0x1fffffffffffff8p+967-0x1fffffffffffff8p+967i", infmm, ErrRange},
	 162  		// a little too large
	 163  		{"1e308+1e308i", 1e+308 + 1e+308i, nil},
	 164  		{"2e308+2e308i", infpp, ErrRange},
	 165  		{"1e309+1e309i", infpp, ErrRange},
	 166  		{"0x1p1025+0x1p1025i", infpp, ErrRange},
	 167  		{"2e308", infp0, ErrRange},
	 168  		{"1e309", infp0, ErrRange},
	 169  		{"0x1p1025", infp0, ErrRange},
	 170  		{"2e308i", inf0p, ErrRange},
	 171  		{"1e309i", inf0p, ErrRange},
	 172  		{"0x1p1025i", inf0p, ErrRange},
	 173  		// way too large
	 174  		{"+1e310+1e310i", infpp, ErrRange},
	 175  		{"+1e310-1e310i", infpm, ErrRange},
	 176  		{"-1e310+1e310i", infmp, ErrRange},
	 177  		{"-1e310-1e310i", infmm, ErrRange},
	 178  		// under/overflow exponent
	 179  		{"1e-4294967296", 0, nil},
	 180  		{"1e-4294967296i", 0, nil},
	 181  		{"1e-4294967296+1i", 1i, nil},
	 182  		{"1+1e-4294967296i", 1, nil},
	 183  		{"1e-4294967296+1e-4294967296i", 0, nil},
	 184  		{"1e+4294967296", infp0, ErrRange},
	 185  		{"1e+4294967296i", inf0p, ErrRange},
	 186  		{"1e+4294967296+1e+4294967296i", infpp, ErrRange},
	 187  		{"1e+4294967296-1e+4294967296i", infpm, ErrRange},
	 188  	}
	 189  	for i := range tests {
	 190  		test := &tests[i]
	 191  		if test.err != nil {
	 192  			test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err}
	 193  		}
	 194  		got, err := ParseComplex(test.in, 128)
	 195  		if !reflect.DeepEqual(err, test.err) {
	 196  			t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
	 197  		}
	 198  		if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out {
	 199  			t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
	 200  		}
	 201  
	 202  		if complex128(complex64(test.out)) == test.out {
	 203  			got, err := ParseComplex(test.in, 64)
	 204  			if !reflect.DeepEqual(err, test.err) {
	 205  				t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
	 206  			}
	 207  			got64 := complex64(got)
	 208  			if complex128(got64) != test.out {
	 209  				t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
	 210  			}
	 211  		}
	 212  	}
	 213  }
	 214  
	 215  // Issue 42297: allow ParseComplex(s, not_32_or_64) for legacy reasons
	 216  func TestParseComplexIncorrectBitSize(t *testing.T) {
	 217  	const s = "1.5e308+1.0e307i"
	 218  	const want = 1.5e308 + 1.0e307i
	 219  
	 220  	for _, bitSize := range []int{0, 10, 100, 256} {
	 221  		c, err := ParseComplex(s, bitSize)
	 222  		if err != nil {
	 223  			t.Fatalf("ParseComplex(%q, %d) gave error %s", s, bitSize, err)
	 224  		}
	 225  		if c != want {
	 226  			t.Fatalf("ParseComplex(%q, %d) = %g (expected %g)", s, bitSize, c, want)
	 227  		}
	 228  	}
	 229  }
	 230  

View as plain text