/// <summary> /// Converts a string to a number (used by parseFloat). /// </summary> /// <param name="input"> The string to convert. </param> /// <returns> The result of parsing the string as a number. </returns> internal static double ParseFloat(string input) { var reader = new System.IO.StringReader(input); // Skip whitespace and line terminators. while (IsWhiteSpaceOrLineTerminator(reader.Peek())) { reader.Read(); } // The number can start with a plus or minus sign. bool negative = false; int firstChar = reader.Read(); switch (firstChar) { case '-': negative = true; firstChar = reader.Read(); break; case '+': firstChar = reader.Read(); break; } // Infinity or -Infinity are also valid. if (firstChar == 'I') { var nfinityString = reader.ReadToEnd(); if (nfinityString == null) { throw new InvalidOperationException("Reader returned null."); } if (nfinityString.StartsWith("nfinity", StringComparison.Ordinal)) { return(negative ? double.NegativeInfinity : double.PositiveInfinity); } } // Empty strings return NaN. if ((firstChar < '0' || firstChar > '9') && firstChar != '.') { return(double.NaN); } // Parse the number. NumberParser.ParseCoreStatus status; var result = NumberParser.ParseCore(reader, (char)firstChar, out status, false, false); // Handle various error cases. if (status == ParseCoreStatus.NoDigits) { return(double.NaN); } return(negative ? -result : result); }
/// <summary> /// Converts a string to a number (used in type coercion). /// </summary> /// <returns> The result of parsing the string as a number. </returns> internal static double CoerceToNumber(string input) { var reader = new System.IO.StringReader(input); // Skip whitespace and line terminators. while (IsWhiteSpaceOrLineTerminator(reader.Peek())) { reader.Read(); } // Empty strings return 0. int firstChar = reader.Read(); if (firstChar == -1) { return(0.0); } // The number can start with a plus or minus sign. bool negative = false; switch (firstChar) { case '-': negative = true; firstChar = reader.Read(); break; case '+': firstChar = reader.Read(); break; } // Infinity or -Infinity are also valid. if (firstChar == 'I') { var restOfString1 = reader.ReadToEnd(); if (restOfString1 == null) { throw new InvalidOperationException("Reader returned null."); } if (restOfString1.StartsWith("nfinity", StringComparison.Ordinal)) { // Check the end of the string for junk. for (int i = 7; i < restOfString1.Length; i++) { if (IsWhiteSpaceOrLineTerminator(restOfString1[i]) == false) { return(double.NaN); } } return(negative ? double.NegativeInfinity : double.PositiveInfinity); } } // Return NaN if the first digit is not a number or a period. if ((firstChar < '0' || firstChar > '9') && firstChar != '.') { return(double.NaN); } // Parse the number. NumberParser.ParseCoreStatus status; double result = NumberParser.ParseCore(reader, (char)firstChar, out status, true, false); // Handle various error cases. switch (status) { case ParseCoreStatus.NoDigits: case ParseCoreStatus.NoExponent: return(double.NaN); } // Check the end of the string for junk. var nfinityString = reader.ReadToEnd(); if (nfinityString == null) { throw new InvalidOperationException("Reader returned null."); } if (nfinityString.Any(t => IsWhiteSpaceOrLineTerminator(t) == false)) { return(double.NaN); } return(negative ? -result : result); }