...

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

View as plain text