atoc.go 3.0 KB

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