public uint160(uint160 b) : this() { for (int i = 0; i < nWidth; i++) { pn[i] = b.pn[i]; } }
public static uint160 operator ~(uint160 a) { var ret = new uint160(); for (int i = 0; i < a.nWidth; i++) { ret.pn[i] = ~a.pn[i]; } return ret; }
public static uint160 operator >>(uint160 a, int shift) { var result = new uint160(); int k = shift / 32; shift = shift % 32; for (int i = 0; i < a.nWidth; i++) { if (i - k - 1 >= 0 && shift != 0) { result.pn[i - k - 1] |= (a.pn[i] << (32 - shift)); } if (i - k >= 0) { result.pn[i - k] |= (a.pn[i] >> shift); } } return result; }
public static uint160 operator %(uint160 a, uint160 b) { if (b.bits <= 32) { return a % b.Low32; } uint160 result = new uint160(); uint[] quotient; uint[] remainder_value; int m = a.bits / 32 + (a.bits % 32 != 0 ? 1 : 0); int n = b.bits / 32 + (b.bits % 32 != 0 ? 1 : 0); BignumHelper.DivModUnsigned(a.pn.Take(m).ToArray(), b.pn.Take(n).ToArray(), out quotient, out remainder_value); remainder_value.CopyTo(result.pn, 0); return result; }
public static uint160 operator <<(uint160 a, int shift) { var result = new uint160(); int k = shift / 32; shift = shift % 32; for (int i = 0; i < a.nWidth; i++) { if (i + k + 1 < a.nWidth && shift != 0) { result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); } if (i + k < a.nWidth) { result.pn[i + k] |= (a.pn[i] << shift); } } return result; }
public static uint160 operator *(uint160 a, uint160 b) { if (!a || !b) { // Multiplication by zero results with zero. return 0; } else if (b.bits <= 32) { if (b.pn[0] == 1) { // If right is 1 then return left operand value return a; } return a * b.pn[0]; } else if (a.bits <= 32) { if (a.pn[0] == 1) { // If left is 1 then return right operand value return b; } return b * a.pn[0]; } int m = a.bits / 32 + (a.bits % 32 != 0 ? 1 : 0); int n = b.bits / 32 + (b.bits % 32 != 0 ? 1 : 0); uint160 result = new uint160(); uint[] left = a.pn.Take(m).ToArray(); uint[] right = b.pn.Take(n).ToArray(); for (int i = 0; i < m; ++i) { uint ai = left[i]; int k = i; ulong temp = 0; for (int j = 0; j < n; ++j) { temp = temp + ((ulong)ai) * right[j] + result.pn[k]; result.pn[k++] = (uint)temp; temp >>= 32; } while (temp != 0) { temp += result.pn[k]; result.pn[k++] = (uint)temp; temp >>= 32; } } return result; }
public static uint160 operator *(uint160 a, ulong multiplier) { var result = new uint160(); ulong c = 0; uint i = 0; do { c += a.pn[i] * multiplier; result.pn[i] = (uint)c; c >>= 32; } while (++i < result.nWidth); return result; }
public static uint160 operator /(uint160 a, uint divisor) { var result = new uint160(); ulong r = 0; int i = a.nWidth; while (i-- > 0) { r <<= 32; r |= a.pn[i]; result.pn[i] = (uint)(r / divisor); r %= divisor; } return result; }
public static uint160 operator +(uint160 a, uint160 b) { var result = new uint160(); ulong carry = 0; for (int i = 0; i < result.nWidth; i++) { ulong n = carry + a.pn[i] + b.pn[i]; result.pn[i] = (uint)(n & 0xffffffff); carry = n >> 32; } return result; }
public static uint160 operator |(uint160 a, uint160 b) { var result = new uint160(); result.pn = new uint[a.nWidth]; for (int i = 0; i < result.nWidth; i++) { result.pn[i] = a.pn[i] | b.pn[i]; } return result; }