Rhino.ScriptRuntime.StringToNumber C# (CSharp) Method

StringToNumber() static private method

static private StringToNumber ( string s, int start, int radix ) : double
s string
start int
radix int
return double
		internal static double StringToNumber(string s, int start, int radix)
		{
			char digitMax = '9';
			char lowerCaseBound = 'a';
			char upperCaseBound = 'A';
			int len = s.Length;
			if (radix < 10)
			{
				digitMax = (char)('0' + radix - 1);
			}
			if (radix > 10)
			{
				lowerCaseBound = (char)('a' + radix - 10);
				upperCaseBound = (char)('A' + radix - 10);
			}
			int end;
			double sum = 0.0;
			for (end = start; end < len; end++)
			{
				char c = s[end];
				int newDigit;
				if ('0' <= c && c <= digitMax)
				{
					newDigit = c - '0';
				}
				else
				{
					if ('a' <= c && c < lowerCaseBound)
					{
						newDigit = c - 'a' + 10;
					}
					else
					{
						if ('A' <= c && c < upperCaseBound)
						{
							newDigit = c - 'A' + 10;
						}
						else
						{
							break;
						}
					}
				}
				sum = sum * radix + newDigit;
			}
			if (start == end)
			{
				return NaN;
			}
			if (sum >= 9007199254740992.0)
			{
				if (radix == 10)
				{
					try
					{
						return System.Double.Parse(Sharpen.Runtime.Substring(s, start, end));
					}
					catch (FormatException)
					{
						return NaN;
					}
				}
				else
				{
					if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
					{
						int bitShiftInChar = 1;
						int digit = 0;
						int SKIP_LEADING_ZEROS = 0;
						int FIRST_EXACT_53_BITS = 1;
						int AFTER_BIT_53 = 2;
						int ZEROS_AFTER_54 = 3;
						int MIXED_AFTER_54 = 4;
						int state = SKIP_LEADING_ZEROS;
						int exactBitsLimit = 53;
						double factor = 0.0;
						bool bit53 = false;
						// bit54 is the 54th bit (the first dropped from the mantissa)
						bool bit54 = false;
						for (; ; )
						{
							if (bitShiftInChar == 1)
							{
								if (start == end)
								{
									break;
								}
								digit = s[start++];
								if ('0' <= digit && digit <= '9')
								{
									digit -= '0';
								}
								else
								{
									if ('a' <= digit && digit <= 'z')
									{
										digit -= 'a' - 10;
									}
									else
									{
										digit -= 'A' - 10;
									}
								}
								bitShiftInChar = radix;
							}
							bitShiftInChar >>= 1;
							bool bit = (digit & bitShiftInChar) != 0;
							switch (state)
							{
								case SKIP_LEADING_ZEROS:
								{
									if (bit)
									{
										--exactBitsLimit;
										sum = 1.0;
										state = FIRST_EXACT_53_BITS;
									}
									break;
								}

								case FIRST_EXACT_53_BITS:
								{
									sum *= 2.0;
									if (bit)
									{
										sum += 1.0;
									}
									--exactBitsLimit;
									if (exactBitsLimit == 0)
									{
										bit53 = bit;
										state = AFTER_BIT_53;
									}
									break;
								}

								case AFTER_BIT_53:
								{
									bit54 = bit;
									factor = 2.0;
									state = ZEROS_AFTER_54;
									break;
								}

								case ZEROS_AFTER_54:
								{
									if (bit)
									{
										state = MIXED_AFTER_54;
									}
									goto case MIXED_AFTER_54;
								}

								case MIXED_AFTER_54:
								{
									// fallthrough
									factor *= 2;
									break;
								}
							}
						}
						switch (state)
						{
							case SKIP_LEADING_ZEROS:
							{
								sum = 0.0;
								break;
							}

							case FIRST_EXACT_53_BITS:
							case AFTER_BIT_53:
							{
								// do nothing
								break;
							}

							case ZEROS_AFTER_54:
							{
								// x1.1 -> x1 + 1 (round up)
								// x0.1 -> x0 (round down)
								if (bit54 & bit53)
								{
									sum += 1.0;
								}
								sum *= factor;
								break;
							}

							case MIXED_AFTER_54:
							{
								// x.100...1.. -> x + 1 (round up)
								// x.0anything -> x (round down)
								if (bit54)
								{
									sum += 1.0;
								}
								sum *= factor;
								break;
							}
						}
					}
				}
			}
			return sum;
		}
ScriptRuntime