/// <summary> /// Creates a complex number based on a string. The string can be in the /// following formats (without the quotes): 'n', 'ni', 'n +/- ni', /// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double. /// </summary> /// <returns> /// A complex number containing the value specified by the given string. /// </returns> /// <param name="value"> /// the string to parse. /// </param> /// <param name="formatProvider"> /// An <see cref="IFormatProvider"/> that supplies culture-specific /// formatting information. /// </param> public static Complex ToComplex(this string value, IFormatProvider formatProvider) { if (value == null) { throw new ArgumentNullException(nameof(value)); } value = value.Trim(); if (value.Length == 0) { throw new FormatException(); } // strip out parens if (value.StartsWith("(", StringComparison.Ordinal)) { if (!value.EndsWith(")", StringComparison.Ordinal)) { throw new FormatException(); } value = value.Substring(1, value.Length - 2).Trim(); } // keywords var numberFormatInfo = formatProvider.GetNumberFormatInfo(); var textInfo = formatProvider.GetTextInfo(); var keywords = new[] { textInfo.ListSeparator, numberFormatInfo.NaNSymbol, numberFormatInfo.NegativeInfinitySymbol, numberFormatInfo.PositiveInfinitySymbol, "+", "-", "i", "j" }; // lexing var tokens = new LinkedList <string>(); GlobalizationHelper.Tokenize(tokens.AddFirst(value), keywords, 0); var token = tokens.First; // parse the left part var leftPart = ParsePart(ref token, out var isLeftPartImaginary, formatProvider); if (token == null) { return(isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(leftPart, 0)); } // parse the right part if (token.Value == textInfo.ListSeparator) { // format: real,imag token = token.Next; if (isLeftPartImaginary) { // left must not contain 'i', right doesn't matter. throw new FormatException(); } var rightPart = ParsePart(ref token, out _, formatProvider); return(new Complex(leftPart, rightPart)); } else { // format: real + imag var rightPart = ParsePart(ref token, out var isRightPartImaginary, formatProvider); if (!(isLeftPartImaginary ^ isRightPartImaginary)) { // either left or right part must contain 'i', but not both. throw new FormatException(); } return(isLeftPartImaginary ? new Complex(rightPart, leftPart) : new Complex(leftPart, rightPart)); } }
/// <summary> /// Creates a complex number based on a string. The string can be in the /// following formats (without the quotes): 'n', 'ni', 'n +/- ni', /// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double. /// </summary> /// <returns> /// A complex number containing the value specified by the given string. /// </returns> /// <param name="value"> /// the string to parse. /// </param> /// <param name="formatProvider"> /// An <see cref="IFormatProvider"/> that supplies culture-specific /// formatting information. /// </param> public static Complex ToComplex(this string value, IFormatProvider formatProvider) { if (value == null) { throw new ArgumentNullException("value"); } value = value.Trim(); if (value.Length == 0) { throw new FormatException(); } // strip out parens if (value.StartsWith("(", StringComparison.Ordinal)) { if (!value.EndsWith(")", StringComparison.Ordinal)) { throw new FormatException(); } value = value.Substring(1, value.Length - 2).Trim(); } // keywords var numberFormatInfo = formatProvider.GetNumberFormatInfo(); var textInfo = formatProvider.GetTextInfo(); var keywords = new[] { textInfo.ListSeparator, numberFormatInfo.NaNSymbol, numberFormatInfo.NegativeInfinitySymbol, numberFormatInfo.PositiveInfinitySymbol, "+", "-", "i", "j" }; // lexing var tokens = new LinkedList<string>(); GlobalizationHelper.Tokenize(tokens.AddFirst(value), keywords, 0); var token = tokens.First; // parse the left part bool isLeftPartImaginary; var leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider); if (token == null) { return isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(leftPart, 0); } // parse the right part if (token.Value == textInfo.ListSeparator) { // format: real,imag token = token.Next; if (isLeftPartImaginary) { // left must not contain 'i', right doesn't matter. throw new FormatException(); } bool isRightPartImaginary; var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider); return new Complex(leftPart, rightPart); } else { // format: real + imag bool isRightPartImaginary; var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider); if (!(isLeftPartImaginary ^ isRightPartImaginary)) { // either left or right part must contain 'i', but not both. throw new FormatException(); } return isLeftPartImaginary ? new Complex(rightPart, leftPart) : new Complex(leftPart, rightPart); } }