sharp-biginteger/Integer.cs

223 lines
4.7 KiB
C#

using System;
using sharp.extensions;
namespace BigInt
{
public class Integer: IntBase
{
public static readonly Integer ZERO = new Integer();
public static readonly Integer ONE = new Integer(new UInt32[] { 1 });
public Integer()
{
this.RawValue = new UInt32[1];
}
public Integer(UInt32[] value)
{
this.RawValue = BigIntMath.reduceSigned(value);
}
public Integer(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.reduceSigned(v);
}
public Integer(UInt32[] value, IntField field)
{
this.RawValue = BigIntMath.reduceSigned(value);
}
public Integer(Integer src)
{
this.RawValue = src.RawValue;
}
public bool Sign(){
return BigIntMath.sign(rawValue);
}
public int Log2(){
return BigIntMath.log2(rawValue);
}
public Integer Pow(int n)
{
if (n == 0)
{
return ONE;
}
else if (n == 1)
{
return this;
}
else if (n > 1)
{
Integer result = this;
n--;
while ((n--) > 0)
{
result = (result * this);
}
return result;
}
throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
}
public Integer Ones()
{
UInt32[] result = BigIntMath.ones(rawValue);
return new Integer(result);
}
public Integer Twos()
{
UInt32[] result = BigIntMath.twos(rawValue);
return new Integer(result);
}
public static Integer fromHexString(string hex)
{
return new Integer(HexString.toBytes(hex).Reverse());
}
public override string ToString()
{
return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, toHexString(), Sign() );
}
private Integer __op_add(Integer b)
{
int width = (rawValue.Length > b.RawValue.Length ? rawValue.Length : b.RawValue.Length) + 1;
UInt32[] v = BigIntMath.extendSigned(rawValue, width);
UInt32[] vb = BigIntMath.extendSigned(b.RawValue, width);
return new Integer(BigIntMath.reduceSigned(BigIntMath.add(v,vb)));
}
private Integer __op_sub(Integer b)
{
int width = (rawValue.Length > b.RawValue.Length ? rawValue.Length : b.RawValue.Length) + 1;
UInt32[] v = BigIntMath.extendSigned(rawValue, width);
UInt32[] vb = BigIntMath.extendSigned(b.RawValue, width);
return new Integer(BigIntMath.reduceSigned(BigIntMath.sub(v,vb)));
}
private int __op_cmp(Integer b)
{
return BigIntMath.cmp(rawValue, b.RawValue);
}
private Integer __op_div(Integer b)
{
UInt32[] result = BigIntMath.sdiv(rawValue, b.RawValue);
return new Integer(result);
}
private Integer __op_mod(Integer b)
{
UInt32[] result = BigIntMath.smod(rawValue, b.RawValue);
return new Integer(result);
}
private Integer __op_mul(Integer b)
{
UInt32[] value = BigIntMath.smul(rawValue, b.RawValue);
return new Integer(value);
}
private Integer __op_new(uint[] value)
{
return new Integer(value);
}
private Integer __op_shl(int b)
{
UInt32[] value = BigIntMath.extendSigned(rawValue, RawValue.Length + ((b + 31) >> 5));
BigIntMath.shl(value,b);
return new Integer(value);
}
private Integer __op_shr(int b)
{
UInt32[] value = rawValue.Segment(0);
BigIntMath.shr(value, b);
return new Integer(value);
}
public static implicit operator Integer(UInteger ui)
{
return new Integer( BigIntMath.signedFromUnsigned( ui.RawValue ));
}
public static implicit operator Integer(int i)
{
return new Integer(new UInt32[]{(UInt32)i});
}
public static Integer operator +(Integer a, Integer b)
{
return a.__op_add(b);
}
public static Integer operator -(Integer a, Integer b)
{
return a.__op_sub(b);
}
public static Integer operator *(Integer a, Integer b)
{
return a.__op_mul(b);
}
public static Integer operator /(Integer a, Integer b)
{
return a.__op_div(b);
}
public static Integer operator %(Integer a, Integer b)
{
return a.__op_mod(b);
}
public static bool operator <(Integer a, Integer b)
{
return a.__op_cmp(b) < 0;
}
public static bool operator >(Integer a, Integer b)
{
return a.__op_cmp(b) > 0;
}
public static bool operator ==(Integer a, Integer 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 !=(Integer a, Integer b)
{
return a.__op_cmp(b) != 0;
}
public static Integer operator <<(Integer a, int b)
{
return a.__op_shl(b);
}
public static Integer operator >>(Integer a, int b)
{
return a.__op_shr(b);
}
}
}