public BigIntegerBC Remainder(
			BigIntegerBC n)
		{
			if (n.sign == 0)
				throw new ArithmeticException("Division by zero error");

			if (this.sign == 0)
				return Zero;

			// For small values, use fast remainder method
			if (n.magnitude.Length == 1)
			{
				int val = n.magnitude[0];

				if (val > 0)
				{
					if (val == 1)
						return Zero;

					// TODO Make this func work on uint, and handle val == 1?
					int rem = Remainder(val);

					return rem == 0
						? Zero
						: new BigIntegerBC(sign, new int[] { rem }, false);
				}
			}

			if (CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude) < 0)
				return this;

			int[] result;
			if (n.QuickPow2Check())  // n is power of two
			{
				// TODO Move before small values branch above?
				result = LastNBits(n.Abs().BitLength - 1);
			}
			else
			{
				result = (int[])this.magnitude.Clone();
				result = Remainder(result, n.magnitude);
			}

			return new BigIntegerBC(sign, result, true);
		}
		public BigIntegerBC Multiply(
			BigIntegerBC val)
		{
			if (sign == 0 || val.sign == 0)
				return Zero;

			if (val.QuickPow2Check()) // val is power of two
			{
				BigIntegerBC result = this.ShiftLeft(val.Abs().BitLength - 1);
				return val.sign > 0 ? result : result.Negate();
			}

			if (this.QuickPow2Check()) // this is power of two
			{
				BigIntegerBC result = val.ShiftLeft(this.Abs().BitLength - 1);
				return this.sign > 0 ? result : result.Negate();
			}

			int maxBitLength = this.BitLength + val.BitLength;
			int resLength = (maxBitLength + BitsPerInt - 1) / BitsPerInt;

			int[] res = new int[resLength];

			if (val == this)
			{
				Square(res, this.magnitude);
			}
			else
			{
				Multiply(res, this.magnitude, val.magnitude);
			}

			return new BigIntegerBC(sign * val.sign, res, true);
		}
		public BigIntegerBC[] DivideAndRemainder(
			BigIntegerBC val)
		{
			if (val.sign == 0)
				throw new ArithmeticException("Division by zero error");

			BigIntegerBC[] biggies = new BigIntegerBC[2];

			if (sign == 0)
			{
				biggies[0] = Zero;
				biggies[1] = Zero;
			}
			else if (val.QuickPow2Check()) // val is power of two
			{
				int e = val.Abs().BitLength - 1;
				BigIntegerBC quotient = this.Abs().ShiftRight(e);
				int[] remainder = this.LastNBits(e);

				biggies[0] = val.sign == this.sign ? quotient : quotient.Negate();
				biggies[1] = new BigIntegerBC(this.sign, remainder, true);
			}
			else
			{
				int[] remainder = (int[])this.magnitude.Clone();
				int[] quotient = Divide(remainder, val.magnitude);

				biggies[0] = new BigIntegerBC(this.sign * val.sign, quotient, true);
				biggies[1] = new BigIntegerBC(this.sign, remainder, true);
			}

			return biggies;
		}
		public BigIntegerBC Gcd(
			BigIntegerBC value)
		{
			if (value.sign == 0)
				return Abs();

			if (sign == 0)
				return value.Abs();

			BigIntegerBC r;
			BigIntegerBC u = this;
			BigIntegerBC v = value;

			while (v.sign != 0)
			{
				r = u.Mod(v);
				u = v;
				v = r;
			}

			return u;
		}
		public BigIntegerBC Divide(
			BigIntegerBC val)
		{
			if (val.sign == 0)
				throw new ArithmeticException("Division by zero error");

			if (sign == 0)
				return Zero;

			if (val.QuickPow2Check()) // val is power of two
			{
				BigIntegerBC result = this.Abs().ShiftRight(val.Abs().BitLength - 1);
				return val.sign == this.sign ? result : result.Negate();
			}

			int[] mag = (int[])this.magnitude.Clone();

			return new BigIntegerBC(this.sign * val.sign, Divide(mag, val.magnitude), true);
		}