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); } } }