github.com/hedzr/evendeep@v0.4.8/internal/cl/parsecomplex_elder.go (about)

     1  //go:build !go1.15
     2  // +build !go1.15
     3  
     4  // for lower than go1.15
     5  
     6  package cl
     7  
     8  import (
     9  	"gopkg.in/hedzr/errors.v3"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  // FormatComplex converts the complex number c to a string of the
    15  // form (a+bi) where a and b are the real and imaginary parts,
    16  // formatted according to the format fmt and precision prec.
    17  //
    18  // The format fmt and precision prec have the same meaning as in FormatFloat.
    19  // It rounds the result assuming that the original was obtained from a complex
    20  // value of bitSize bits, which must be 64 for complex64 and 128 for complex128.
    21  func FormatComplex(c complex128, fmt byte, prec, bitSize int) string {
    22  	if bitSize != 64 && bitSize != 128 {
    23  		panic("invalid bitSize")
    24  	}
    25  	bitSize >>= 1 // complex64 uses float32 internally
    26  
    27  	// Check if imaginary part has a sign. If not, add one.
    28  	im := strconv.FormatFloat(imag(c), fmt, prec, bitSize)
    29  	if im[0] != '+' && im[0] != '-' {
    30  		im = "+" + im
    31  	}
    32  
    33  	return "(" + strconv.FormatFloat(real(c), fmt, prec, bitSize) + im + "i)"
    34  }
    35  
    36  // ParseComplexSimple converts a string to complex number.
    37  //
    38  // Examples:
    39  //
    40  //	c1 := cmdr.ParseComplex("3-4i")
    41  //	c2 := cmdr.ParseComplex("3.13+4.79i")
    42  func ParseComplexSimple(s string) (v complex128) {
    43  	return a2complexShort(s)
    44  }
    45  
    46  // ParseComplex converts a string to complex number.
    47  // If the string is not valid complex format, return err not nil.
    48  //
    49  // Examples:
    50  //
    51  //	c1 := cmdr.ParseComplex("3-4i")
    52  //	c2 := cmdr.ParseComplex("3.13+4.79i")
    53  func ParseComplex(s string) (v complex128, err error) {
    54  	return a2complex(s)
    55  }
    56  
    57  func a2complexShort(s string) (v complex128) {
    58  	v, _ = a2complex(s)
    59  	return
    60  }
    61  
    62  func a2complex(s string) (v complex128, err error) {
    63  	s = strings.TrimSpace(strings.TrimRightFunc(strings.TrimLeftFunc(s, func(r rune) bool {
    64  		return r == '('
    65  	}), func(r rune) bool {
    66  		return r == ')'
    67  	}))
    68  
    69  	var sign float64
    70  	if s[0] == '-' {
    71  		sign, s = -1, s[1:]
    72  	} else {
    73  		sign = 1
    74  	}
    75  
    76  	if i := strings.IndexAny(s, "+-"); i >= 0 {
    77  		rr, ii := s[0:i], s[i:]
    78  		if j := strings.Index(ii, "i"); j >= 0 {
    79  			var ff, fi float64
    80  			ff, err = strconv.ParseFloat(strings.TrimSpace(rr), 64)
    81  			if err != nil {
    82  				return
    83  			}
    84  			fi, err = strconv.ParseFloat(strings.TrimSpace(ii[0:j]), 64)
    85  			if err != nil {
    86  				return
    87  			}
    88  
    89  			v = complex(ff*sign, fi)
    90  			return
    91  		}
    92  		err = errors.New("for a complex number, the imaginary part should end with 'i', such as '3+4i'")
    93  		return
    94  
    95  		// err = errors.New("not valid complex number.")
    96  	}
    97  
    98  	var ff float64
    99  	ff, err = strconv.ParseFloat(strings.TrimSpace(s), 64)
   100  	if err != nil {
   101  		return
   102  	}
   103  	v = complex(ff, 0)
   104  	return
   105  }