github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/strconv/atoc_test.go (about) 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 }