--- ./Runtime/Microsoft.Dynamic/Math/BigIntegerV2.cs 2009-10-19 13:36:38.000000000 -0400
+++ /cvs/mcs/class/System.Numerics/System.Numerics/BigInteger.cs 2009-10-31 12:13:55.000000000 -0400
@@ -12,7 +12,6 @@
*
*
* ***************************************************************************/
-#if CLR2
using System;
using System.Collections.Generic;
@@ -20,8 +19,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
-using Microsoft.Contracts;
-using Microsoft.Scripting.Utils;
namespace Microsoft.Scripting.Math {
///
@@ -104,7 +101,8 @@
/// (inverse of ToByteArray())
///
public static BigInteger Create(byte[] v) {
- ContractUtils.RequiresNotNull(v, "v");
+ if (v == null)
+ throw new ArgumentNullException ("v");
if (v.Length == 0) return Create(0);
int byteCount = v.Length;
@@ -339,10 +337,13 @@
[CLSCompliant(false)]
public BigInteger(int sign, params uint[] data) {
- ContractUtils.RequiresNotNull(data, "data");
- ContractUtils.Requires(sign >= -1 && sign <= +1, "sign");
+ if (data == null)
+ throw new ArgumentNullException ("data");
+ if (!(sign >= -1 && sign <= +1))
+ throw new ArgumentException ("sign");
int length = GetLength(data);
- ContractUtils.Requires(length == 0 || sign != 0, "sign");
+ if (!(length == 0 || sign != 0))
+ throw new ArgumentException ("sign");
this.data = data;
this.sign = (short)(length == 0 ? 0 : sign);
@@ -507,7 +508,7 @@
}
public bool TryToFloat64(out double result) {
- return StringUtils.TryParseDouble(ToString(10),
+ return double.TryParse(ToString(10),
System.Globalization.NumberStyles.Number,
System.Globalization.CultureInfo.InvariantCulture.NumberFormat,
out result);
@@ -1355,17 +1356,92 @@
return this * this;
}
- [Confined]
public override string ToString() {
return ToString(10);
}
- [Confined]
- public string ToString(int radix) {
- return MathUtils.BigIntegerToString(copy(data), sign, radix);
+ // generated by scripts/radix_generator.py
+ private static readonly uint[] maxCharsPerDigit = { 0, 0, 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
+ private static readonly uint[] groupRadixValues = { 0, 0, 2147483648, 3486784401, 1073741824, 1220703125, 2176782336, 1977326743, 1073741824, 3486784401, 1000000000, 2357947691, 429981696, 815730721, 1475789056, 2562890625, 268435456, 410338673, 612220032, 893871739, 1280000000, 1801088541, 2494357888, 3404825447, 191102976, 244140625, 308915776, 387420489, 481890304, 594823321, 729000000, 887503681, 1073741824, 1291467969, 1544804416, 1838265625, 2176782336 };
+
+ public static ArgumentOutOfRangeException MakeArgumentOutOfRangeException(string paramName, object actualValue, string message) {
+ return new ArgumentOutOfRangeException(paramName, string.Format("{0} (actual value is '{1}')", message, actualValue));
+ }
+
+ internal static string BigIntegerToString(uint[] d, int sign, int radix) {
+ if (radix < 2) {
+ throw MakeArgumentOutOfRangeException("radix", radix, "radix must be >= 2");
+ }
+ if (radix > 36) {
+ throw MakeArgumentOutOfRangeException("radix", radix, "radix must be <= 36");
+ }
+
+ int dl = d.Length;
+ if (dl == 0) {
+ return "0";
+ }
+
+ List digitGroups = new List();
+
+ uint groupRadix = groupRadixValues[radix];
+ while (dl > 0) {
+ uint rem = div(d, ref dl, groupRadix);
+ digitGroups.Add(rem);
+ }
+
+ StringBuilder ret = new StringBuilder();
+ if (sign == -1) {
+ ret.Append("-");
+ }
+
+ int digitIndex = digitGroups.Count - 1;
+
+ char[] tmpDigits = new char[maxCharsPerDigit[radix]];
+
+ AppendRadix((uint)digitGroups[digitIndex--], (uint)radix, tmpDigits, ret, false);
+ while (digitIndex >= 0) {
+ AppendRadix((uint)digitGroups[digitIndex--], (uint)radix, tmpDigits, ret, true);
+ }
+ return ret.Length == 0 ? "0" : ret.ToString();
+ }
+
+ private static uint div(uint[] n, ref int nl, uint d) {
+ ulong rem = 0;
+ int i = nl;
+ bool seenNonZero = false;
+ while (--i >= 0) {
+ rem <<= BitsPerDigit;
+ rem |= n[i];
+ uint v = (uint)(rem / d);
+ n[i] = v;
+ if (v == 0) {
+ if (!seenNonZero) nl--;
+ } else {
+ seenNonZero = true;
+ }
+ rem %= d;
+ }
+ return (uint)rem;
+ }
+
+ private static void AppendRadix(uint rem, uint radix, char[] tmp, StringBuilder buf, bool leadingZeros) {
+ const string symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ int digits = tmp.Length;
+ int i = digits;
+ while (i > 0 && (leadingZeros || rem != 0)) {
+ uint digit = rem % radix;
+ rem /= radix;
+ tmp[--i] = symbols[(int)digit];
+ }
+ if (leadingZeros) buf.Append(tmp);
+ else buf.Append(tmp, i, digits - i);
+ }
+
+ public string ToString(int radix) {
+ return BigIntegerToString(copy(data), sign, radix);
}
- [Confined]
public override int GetHashCode() {
// The Object.GetHashCode function needs to be consistent with the Object.Equals function.
// Languages that build on top of this may have a more flexible equality function and
@@ -1395,12 +1471,10 @@
}
}
- [Confined]
public override bool Equals(object obj) {
return Equals(obj as BigInteger);
}
- [StateIndependent]
public bool Equals(BigInteger other) {
if (object.ReferenceEquals(other, null)) return false;
return this == other;
@@ -1492,17 +1566,14 @@
#region IConvertible Members
- [Confined]
public TypeCode GetTypeCode() {
return TypeCode.Object;
}
- [Confined]
public bool ToBoolean(IFormatProvider provider) {
return this != Zero;
}
- [Confined]
public byte ToByte(IFormatProvider provider) {
uint ret;
if (AsUInt32(out ret) && (ret & ~0xFF) == 0) {
@@ -1561,7 +1632,6 @@
return trimmedBytes;
}
- [Confined]
public char ToChar(IFormatProvider provider) {
int ret;
if (AsInt32(out ret) && (ret <= Char.MaxValue) && (ret >= Char.MinValue)) {
@@ -1570,24 +1640,20 @@
throw new OverflowException("big integer won't fit into char");
}
- [Confined]
public DateTime ToDateTime(IFormatProvider provider) {
throw new NotImplementedException();
}
- [Confined]
public decimal ToDecimal(IFormatProvider provider) {
decimal ret;
if (AsDecimal(out ret)) return ret;
throw new OverflowException("big integer won't fit into decimal");
}
- [Confined]
public double ToDouble(IFormatProvider provider) {
return ToFloat64();
}
- [Confined]
public short ToInt16(IFormatProvider provider) {
int ret;
if (AsInt32(out ret) && (ret <= short.MaxValue) && (ret >= short.MinValue)) {
@@ -1596,7 +1662,6 @@
throw new OverflowException("big integer won't fit into short");
}
- [Confined]
public int ToInt32(IFormatProvider provider) {
int ret;
if (AsInt32(out ret)) {
@@ -1605,7 +1670,6 @@
throw new OverflowException("big integer won't fit into int");
}
- [Confined]
public long ToInt64(IFormatProvider provider) {
long ret;
if (AsInt64(out ret)) {
@@ -1614,7 +1678,7 @@
throw new OverflowException("big integer won't fit into long");
}
- [CLSCompliant(false), Confined]
+ [CLSCompliant(false)]
public sbyte ToSByte(IFormatProvider provider) {
int ret;
if (AsInt32(out ret) && (ret <= sbyte.MaxValue) && (ret >= sbyte.MinValue)) {
@@ -1623,17 +1687,14 @@
throw new OverflowException("big integer won't fit into sbyte");
}
- [Confined]
public float ToSingle(IFormatProvider provider) {
return checked((float)ToDouble(provider));
}
- [Confined]
public string ToString(IFormatProvider provider) {
return ToString();
}
- [Confined]
public object ToType(Type conversionType, IFormatProvider provider) {
if (conversionType == typeof(BigInteger)) {
return this;
@@ -1641,7 +1702,7 @@
throw new NotImplementedException();
}
- [CLSCompliant(false), Confined]
+ [CLSCompliant(false)]
public ushort ToUInt16(IFormatProvider provider) {
uint ret;
if (AsUInt32(out ret) && ret <= ushort.MaxValue) {
@@ -1650,7 +1711,7 @@
throw new OverflowException("big integer won't fit into ushort");
}
- [CLSCompliant(false), Confined]
+ [CLSCompliant(false)]
public uint ToUInt32(IFormatProvider provider) {
uint ret;
if (AsUInt32(out ret)) {
@@ -1659,7 +1720,7 @@
throw new OverflowException("big integer won't fit into uint");
}
- [CLSCompliant(false), Confined]
+ [CLSCompliant(false)]
public ulong ToUInt64(IFormatProvider provider) {
ulong ret;
if (AsUInt64(out ret)) {
@@ -1724,4 +1785,3 @@
#endregion
}
}
-#endif