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  

View as plain text