int number = 0;
int nDigits = 0;
- bool decimalPointFound = false;
+ int decimalPointPos = -1;
int digitValue;
char hexDigit;
- int exponent = 0;
// Number stuff
do {
(FindOther (ref pos, s, nfi.NumberGroupSeparator)
|| FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
continue;
- else
- if (!decimalPointFound && AllowDecimalPoint &&
+
+ if (AllowDecimalPoint && decimalPointPos < 0 &&
(FindOther (ref pos, s, nfi.NumberDecimalSeparator)
|| FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
- decimalPointFound = true;
+ decimalPointPos = nDigits;
continue;
}
break;
}
+
+ nDigits++;
+
if (AllowHexSpecifier) {
- nDigits++;
hexDigit = s [pos++];
if (Char.IsDigit (hexDigit))
digitValue = (int) (hexDigit - '0');
} else {
number = (int)checked (unumber * 16u + (uint)digitValue);
}
+
+ continue;
}
- else if (decimalPointFound) {
- nDigits++;
- // Allows decimal point as long as it's only
- // followed by zeroes.
- if (s [pos++] != '0') {
- if (!tryParse)
- exc = new OverflowException ("Value too large or too " +
- "small.");
- return false;
- }
- }
- else {
- nDigits++;
-
- try {
- // Calculations done as negative
- // (abs (MinValue) > abs (MaxValue))
- number = checked (
- number * 10 -
- (int) (s [pos++] - '0')
- );
- } catch (OverflowException) {
- if (!tryParse)
- exc = new OverflowException ("Value too large or too " +
- "small.");
- return false;
- }
+
+ try {
+ // Calculations done as negative
+ // (abs (MinValue) > abs (MaxValue))
+ number = checked (number * 10 - (int) (s [pos++] - '0'));
+ } catch (OverflowException) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
}
} while (pos < s.Length);
return false;
}
+ int exponent = 0;
if (AllowExponent)
if (FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
return false;
number = checked (-number);
}
- // result *= 10^exponent
- if (exponent > 0) {
+ if (decimalPointPos >= 0)
+ exponent = exponent - nDigits + decimalPointPos;
+
+ if (exponent < 0) {
+ //
+ // Any non-zero values after decimal point are not allowed
+ //
+ int remainder;
+ number = Math.DivRem (number, (int) Math.Pow (10, -exponent), out remainder);
+ if (remainder != 0) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
+ }
+ } else if (exponent > 0) {
+ //
+ // result *= 10^exponent
+ //
// Reduce the risk of throwing an overflow exc
+ //
double res = checked (Math.Pow (10, exponent) * number);
- if (res < Int32.MinValue || res > Int32.MaxValue) {
+ if (res < MinValue || res > MaxValue) {
if (!tryParse)
exc = new OverflowException ("Value too large or too small.");
return false;
long number = 0;
int nDigits = 0;
- bool decimalPointFound = false;
+ int decimalPointPos = -1;
int digitValue;
char hexDigit;
- int exponent = 0;
// Number stuff
do {
(Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
continue;
- else
- if (!decimalPointFound && AllowDecimalPoint &&
+
+ if (AllowDecimalPoint && decimalPointPos < 0 &&
(Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
- decimalPointFound = true;
+ decimalPointPos = nDigits;
continue;
}
break;
}
+
+ nDigits++;
+
if (AllowHexSpecifier) {
- nDigits++;
hexDigit = s [pos++];
if (Char.IsDigit (hexDigit))
digitValue = (int) (hexDigit - '0');
exc = e;
return false;
}
- }
- else if (decimalPointFound) {
- nDigits++;
- // Allows decimal point as long as it's only
- // followed by zeroes.
- if (s [pos++] != '0') {
- if (!tryParse)
- exc = new OverflowException ("Value too large or too " +
- "small.");
- return false;
- }
- }
- else {
- nDigits++;
- try {
- // Calculations done as negative
- // (abs (MinValue) > abs (MaxValue))
- number = checked (
- number * 10 -
- (long) (s [pos++] - '0')
- );
- } catch (OverflowException) {
- if (!tryParse)
- exc = new OverflowException ("Value too large or too " +
- "small.");
- return false;
- }
+ continue;
}
+
+ try {
+ // Calculations done as negative
+ // (abs (MinValue) > abs (MaxValue))
+ number = checked (number * 10 - (long) (s [pos++] - '0'));
+ } catch (OverflowException) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
+ }
} while (pos < s.Length);
// Post number stuff
return false;
}
+ int exponent = 0;
if (AllowExponent)
if (Int32.FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
return false;
}
}
- // result *= 10^exponent
- if (exponent > 0) {
+ if (decimalPointPos >= 0)
+ exponent = exponent - nDigits + decimalPointPos;
+
+ if (exponent < 0) {
+ //
+ // Any non-zero values after decimal point are not allowed
+ //
+ long remainder;
+ number = Math.DivRem (number, (long) Math.Pow (10, -exponent), out remainder);
+ if (remainder != 0) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
+ }
+ } else if (exponent > 0) {
+ //
+ // result *= 10^exponent
+ //
// Reduce the risk of throwing an overflow exc
+ //
double res = checked (Math.Pow (10, exponent) * number);
- if (res < Int32.MinValue || res > Int32.MaxValue) {
+ if (res < MinValue || res > MaxValue) {
if (!tryParse)
exc = new OverflowException ("Value too large or too small.");
return false;
}
- number = (long) res;
+ number = (long)res;
}
result = number;
uint number = 0;
int nDigits = 0;
- bool decimalPointFound = false;
+ int decimalPointPos = -1;
uint digitValue;
char hexDigit;
- int exponent = 0;
// Number stuff
// Just the same as Int32, but this one adds instead of substract
(Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
continue;
- else
- if (!decimalPointFound && AllowDecimalPoint &&
+
+ if (AllowDecimalPoint && decimalPointPos < 0 &&
(Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
- decimalPointFound = true;
+ decimalPointPos = nDigits;
continue;
}
break;
}
+
+ nDigits++;
+
if (AllowHexSpecifier) {
- nDigits++;
hexDigit = s [pos++];
if (Char.IsDigit (hexDigit))
digitValue = (uint) (hexDigit - '0');
number = (uint) l;
} else
number = checked (number * 16 + digitValue);
+
+ continue;
}
- else if (decimalPointFound) {
- nDigits++;
- // Allows decimal point as long as it's only
- // followed by zeroes.
- if (s [pos++] != '0') {
- if (!tryParse)
- exc = new OverflowException (Locale.GetText ("Value too large or too small."));
- return false;
- }
- }
- else {
- nDigits++;
- try {
- number = checked (number * 10 + (uint) (s [pos++] - '0'));
- }
- catch (OverflowException) {
- if (!tryParse)
- exc = new OverflowException (Locale.GetText ("Value too large or too small."));
- return false;
- }
+ try {
+ number = checked (number * 10 + (uint) (s [pos++] - '0'));
+ } catch (OverflowException) {
+ if (!tryParse)
+ exc = new OverflowException (Locale.GetText ("Value too large or too small."));
+ return false;
}
} while (pos < s.Length);
return false;
}
+ int exponent = 0;
if (AllowExponent)
if (Int32.FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
return false;
return false;
}
- // result *= 10^exponent
- if (exponent > 0) {
+ if (decimalPointPos >= 0)
+ exponent = exponent - nDigits + decimalPointPos;
+
+ if (exponent < 0) {
+ //
+ // Any non-zero values after decimal point are not allowed
+ //
+ long remainder;
+ number = (uint) Math.DivRem (number, (int) Math.Pow (10, -exponent), out remainder);
+ if (remainder != 0) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
+ }
+ } else if (exponent > 0) {
+ //
+ // result *= 10^exponent
+ //
// Reduce the risk of throwing an overflow exc
+ //
double res = checked (Math.Pow (10, exponent) * number);
- if (res < Int32.MinValue || res > Int32.MaxValue) {
+ if (res < MinValue || res > MaxValue) {
if (!tryParse)
exc = new OverflowException ("Value too large or too small.");
return false;
}
- number = (uint) res;
+ number = (uint)res;
}
result = number;
-
return true;
}
ulong number = 0;
int nDigits = 0;
- bool decimalPointFound = false;
+ int decimalPointPos = -1;
ulong digitValue;
char hexDigit;
- int exponent = 0;
// Number stuff
// Just the same as Int32, but this one adds instead of substract
(Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
continue;
- else
- if (!decimalPointFound && AllowDecimalPoint &&
+
+ if (AllowDecimalPoint && decimalPointPos < 0 &&
(Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)
|| Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
- decimalPointFound = true;
+ decimalPointPos = nDigits;
continue;
}
break;
}
+
+ nDigits++;
+
if (AllowHexSpecifier) {
- nDigits++;
hexDigit = s [pos++];
if (Char.IsDigit (hexDigit))
digitValue = (ulong) (hexDigit - '0');
return false;
} else
number = checked (number * 16 + digitValue);
+
+ continue;
}
- else if (decimalPointFound) {
- nDigits++;
- // Allows decimal point as long as it's only
- // followed by zeroes.
- if (s [pos++] != '0') {
- if (!tryParse)
- exc = new OverflowException (Locale.GetText ("Value too large or too small."));
- return false;
- }
- }
- else {
- nDigits++;
- try {
- number = checked (number * 10 + (ulong) (s [pos++] - '0'));
- }
- catch (OverflowException) {
- if (!tryParse)
- exc = new OverflowException (Locale.GetText ("Value too large or too small."));
- return false;
- }
+ try {
+ number = checked (number * 10 + (ulong) (s [pos++] - '0'));
+ } catch (OverflowException) {
+ if (!tryParse)
+ exc = new OverflowException (Locale.GetText ("Value too large or too small."));
+ return false;
}
} while (pos < s.Length);
return false;
}
+ int exponent = 0;
if (AllowExponent)
if (Int32.FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
return false;
return false;
}
- // result *= 10^exponent
- if (exponent > 0) {
+ if (decimalPointPos >= 0)
+ exponent = exponent - nDigits + decimalPointPos;
+
+ if (exponent < 0) {
+ //
+ // Any non-zero values after decimal point are not allowed
+ //
+ long remainder;
+ number = (ulong) Math.DivRem ((long) number, (long) Math.Pow (10, -exponent), out remainder);
+ if (remainder != 0) {
+ if (!tryParse)
+ exc = new OverflowException ("Value too large or too small.");
+ return false;
+ }
+ } else if (exponent > 0) {
+ //
+ // result *= 10^exponent
+ //
// Reduce the risk of throwing an overflow exc
+ //
double res = checked (Math.Pow (10, exponent) * number);
- if (res < Int32.MinValue || res > Int32.MaxValue) {
+ if (res < MinValue || res > MaxValue) {
if (!tryParse)
exc = new OverflowException ("Value too large or too small.");
return false;
}
- number = (ulong) res;
+ number = (ulong)res;
}
result = number;
Assert.AreEqual (2000000, Int32.Parse ("2E6", NumberStyles.AllowExponent), "A#4");
Assert.AreEqual (200, Int32.Parse ("2E+2", NumberStyles.AllowExponent), "A#5");
Assert.AreEqual (2, Int32.Parse ("2", NumberStyles.AllowExponent), "A#6");
+ Assert.AreEqual (21, Int32.Parse ("2.1E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#7");
+ Assert.AreEqual (520, Int32.Parse (".52E3", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#8");
+ Assert.AreEqual (32500000, Int32.Parse ("32.5E6", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#9");
+ Assert.AreEqual (890, Int32.Parse ("8.9000E2", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#10");
try {
Int32.Parse ("2E");
Assert.Fail ("B#8");
} catch (FormatException) {
}
+
+ try {
+ Int32.Parse ("2.09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent);
+ Assert.Fail ("B#9");
+ } catch (OverflowException) {
+ }
}
[Test]
Assert.AreEqual (2000000, long.Parse ("2E6", NumberStyles.AllowExponent), "A#4");
Assert.AreEqual (200, long.Parse ("2E+2", NumberStyles.AllowExponent), "A#5");
Assert.AreEqual (2, long.Parse ("2", NumberStyles.AllowExponent), "A#6");
+ Assert.AreEqual (21, long.Parse ("2.1E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#7");
+ Assert.AreEqual (520, long.Parse (".52E3", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#8");
+ Assert.AreEqual (32500000, long.Parse ("32.5E6", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#9");
+ Assert.AreEqual (890, long.Parse ("8.9000E2", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#10");
try {
long.Parse ("2E");
Assert.Fail ("B#8");
} catch (FormatException) {
}
+
+ try {
+ long.Parse ("2.09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent);
+ Assert.Fail ("B#9");
+ } catch (OverflowException) {
+ }
}
[Test]
Assert.AreEqual (2000000, uint.Parse ("2E6", NumberStyles.AllowExponent), "A#4");
Assert.AreEqual (200, uint.Parse ("2E+2", NumberStyles.AllowExponent), "A#5");
Assert.AreEqual (2, uint.Parse ("2", NumberStyles.AllowExponent), "A#6");
+ Assert.AreEqual (21, uint.Parse ("2.1E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#7");
+ Assert.AreEqual (520, uint.Parse (".52E3", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#8");
+ Assert.AreEqual (32500000, uint.Parse ("32.5E6", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#9");
+ Assert.AreEqual (890, uint.Parse ("8.9000E2", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#10");
try {
uint.Parse ("2E");
Assert.Fail ("B#8");
} catch (FormatException) {
}
+
+ try {
+ uint.Parse ("2.09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent);
+ Assert.Fail ("B#9");
+ } catch (OverflowException) {
+ }
}
[Test]
Assert.AreEqual (2000000, ulong.Parse ("2E6", NumberStyles.AllowExponent), "A#4");
Assert.AreEqual (200, ulong.Parse ("2E+2", NumberStyles.AllowExponent), "A#5");
Assert.AreEqual (2, ulong.Parse ("2", NumberStyles.AllowExponent), "A#6");
+ Assert.AreEqual (21, ulong.Parse ("2.1E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#7");
+ Assert.AreEqual (520, ulong.Parse (".52E3", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#8");
+ Assert.AreEqual (32500000, ulong.Parse ("32.5E6", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#9");
+ Assert.AreEqual (890, ulong.Parse ("8.9000E2", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent), "A#10");
try {
ulong.Parse ("2E");
Assert.Fail ("B#8");
} catch (FormatException) {
}
+
+ try {
+ ulong.Parse ("2.09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent);
+ Assert.Fail ("B#9");
+ } catch (OverflowException) {
+ }
}
[Test]