232 lines
4.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|