sharp-biginteger/UInteger.cs

232 lines
4.8 KiB
C#

using System;
using sharp.extensions;
using System.Text;
using System.CodeDom;
namespace BigInt
{
public class UInteger: IntBase
{
public static readonly UInteger ZERO = new UInteger();
public static readonly UInteger ONE = new UInteger(new UInt32[] { 1 });
public UInteger()
{
this.RawValue = new UInt32[1];
}
public UInteger(UInt32[] value)
{
this.RawValue = BigIntMath.reduceUnsigned(value);
}
public UInteger(byte[] ivalue)
{
UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2];
ivalue = ivalue.Extend(v.Length << 2);
for (int n = 0; n < v.Length; n++)
{
v[n] = BitConverter.ToUInt32(ivalue, n << 2);
}
this.RawValue = BigIntMath.reduceUnsigned(v);
}
public UInteger(UInt32[] value, IntField field)
{
this.RawValue = BigIntMath.reduceUnsigned(value);
}
public UInteger(UInteger src)
{
this.RawValue = src.RawValue;
}
public int Log2()
{
int lg2 = BigIntMath.log2(rawValue);
return lg2 < 0 ? rawValue.Length << 32 : lg2;
}
public UInteger Pow(int n)
{
if (n == 0)
{
return ONE;
}
else if (n == 1)
{
return this;
}
else if (n > 1)
{
UInteger result = this;
n--;
while ((n--) > 0)
{
result = (result * this);
}
return result;
}
throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
}
public UInteger Ones()
{
UInt32[] result = BigIntMath.ones(rawValue);
return new UInteger(result);
}
public UInteger Twos()
{
UInt32[] result = BigIntMath.twos(rawValue);
return new UInteger(result);
}
public static UInteger fromHexString(string hex)
{
return new UInteger(HexString.toBytes(hex).Reverse());
}
private UInteger __op_new(uint[] value)
{
return new UInteger(value);
}
private UInteger __op_add(UInteger b)
{
UInt32[] result = RawValue.Segment(0).Extend(b.RawValue.Length);
BigUIntMath.add(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_sub(UInteger b)
{
UInt32[] result = RawValue.Segment(0).Extend(b.RawValue.Length);
BigUIntMath.sub(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_mul(UInteger b)
{
return new UInteger(BigUIntMath.mul(this.RawValue,b.RawValue));
}
private UInteger __op_div(UInteger b)
{
return new UInteger(BigUIntMath.div(this.RawValue.Segment(0), b.RawValue));
}
private UInteger __op_mod(UInteger b)
{
UInt32[] result = RawValue.Segment(0);
BigUIntMath.div(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_shl(int b)
{
UInt32[] v = this.RawValue.Segment(0);
v = v.Extend(v.Length + ((b + 31) >> 5));
BigUIntMath.shl(v, b);
UInteger r = new UInteger(v);
return r;
}
private UInteger __op_shr(int b)
{
UInteger result = new UInteger(this);
BigUIntMath.shr(result.RawValue,b);
return result;
}
private int __op_cmp(UInteger b)
{
return BigUIntMath.cmp(this.RawValue,b.RawValue);
}
public static implicit operator UInteger(int n)
{
return new UInteger(new UInt32[] { (UInt32)n });
}
public static implicit operator UInteger(uint n)
{
return new UInteger(new UInt32[] { n });
}
public static implicit operator UInteger(UInt64 n)
{
return new UInteger(new UInt32[] { (UInt32)n, (UInt32)(n >> 32) });
}
public static implicit operator UInteger(Integer ui)
{
return new UInteger(ui.RawValue);
}
public static UInteger operator +(UInteger a, UInteger b)
{
return a.__op_add(b);
}
public static UInteger operator -(UInteger a, UInteger b)
{
return a.__op_sub(b);
}
public static UInteger operator *(UInteger a, UInteger b)
{
return a.__op_mul(b);
}
public static UInteger operator /(UInteger a, UInteger b)
{
return a.__op_div(b);
}
public static UInteger operator %(UInteger a, UInteger b)
{
return a.__op_mod(b);
}
public static bool operator <(UInteger a, UInteger b)
{
return a.__op_cmp(b) < 0;
}
public static bool operator >(UInteger a, UInteger b)
{
return a.__op_cmp(b) > 0;
}
public static bool operator ==(UInteger a, UInteger b)
{
if ((object)a == (object)b)
{
return true;
}
if (((object)a == null) || ((object)b == null))
{
return false;
}
return a.__op_cmp(b) == 0;
}
public static bool operator !=(UInteger a, UInteger b)
{
return a.__op_cmp(b) != 0;
}
public static UInteger operator <<(UInteger a, int b)
{
return a.__op_shl(b);
}
public static UInteger operator >>(UInteger a, int b)
{
return a.__op_shr(b);
}
public override bool Equals(object obj)
{
if (typeof(IntBase).IsInstanceOfType(obj)){
IntBase ib = (IntBase)obj;
return BigIntMath.cmp(rawValue, ib.RawValue) == 0;
}
return false;
}
}
}