Source file src/internal/strconv/atoc.go
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 6 7 // ParseComplex converts the string s to a complex number 8 // with the precision specified by bitSize: 64 for complex64, or 128 for complex128. 9 // When bitSize=64, the result still has type complex128, but it will be 10 // convertible to complex64 without changing its value. 11 // 12 // The number represented by s must be of the form N, Ni, or N±Ni, where N stands 13 // for a floating-point number as recognized by [ParseFloat], and i is the imaginary 14 // component. If the second N is unsigned, a + sign is required between the two components 15 // as indicated by the ±. If the second N is NaN, only a + sign is accepted. 16 // The form may be parenthesized and cannot contain any spaces. 17 // The resulting complex number consists of the two components converted by ParseFloat. 18 // 19 // The errors that ParseComplex returns have concrete type [*NumError] 20 // and include err.Num = s. 21 // 22 // If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax. 23 // 24 // If s is syntactically well-formed but either component is more than 1/2 ULP 25 // away from the largest floating point number of the given component's size, 26 // ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component. 27 func ParseComplex(s string, bitSize int) (complex128, error) { 28 size := 64 29 if bitSize == 64 { 30 size = 32 // complex64 uses float32 parts 31 } 32 33 // Remove parentheses, if any. 34 if len(s) >= 2 && s[0] == '(' && s[len(s)-1] == ')' { 35 s = s[1 : len(s)-1] 36 } 37 38 var pending error // pending range error, or nil 39 40 // Read real part (possibly imaginary part if followed by 'i'). 41 re, n, err := parseFloatPrefix(s, size) 42 if err != nil { 43 if err != ErrRange { 44 return 0, err 45 } 46 pending = err 47 } 48 s = s[n:] 49 50 // If we have nothing left, we're done. 51 if len(s) == 0 { 52 return complex(re, 0), pending 53 } 54 55 // Otherwise, look at the next character. 56 switch s[0] { 57 case '+': 58 // Consume the '+' to avoid an error if we have "+NaNi", but 59 // do this only if we don't have a "++" (don't hide that error). 60 if len(s) > 1 && s[1] != '+' { 61 s = s[1:] 62 } 63 case '-': 64 // ok 65 case 'i': 66 // If 'i' is the last character, we only have an imaginary part. 67 if len(s) == 1 { 68 return complex(0, re), pending 69 } 70 fallthrough 71 default: 72 return 0, ErrSyntax 73 } 74 75 // Read imaginary part. 76 im, n, err := parseFloatPrefix(s, size) 77 if err != nil { 78 if err != ErrRange { 79 return 0, err 80 } 81 pending = err 82 } 83 s = s[n:] 84 if s != "i" { 85 return 0, ErrSyntax 86 } 87 return complex(re, im), pending 88 } 89