public static MultiPrecision <N> Div(MultiPrecision <N> a, long b) { if (a.IsNaN) { return(NaN); } if (a.IsZero) { if (b == 0) { return(NaN); } return((a.Sign == UIntUtil.Sign(b)) ? Zero : MinusZero); } if (!a.IsFinite) { return((a.Sign == UIntUtil.Sign(b)) ? PositiveInfinity : NegativeInfinity); } if (b == 0) { return((a.Sign == Sign.Plus) ? PositiveInfinity : NegativeInfinity); } if (b == 1) { return(a); } if (b == -1) { return(Neg(a)); } UInt64 b_abs = UIntUtil.Abs(b); if (UIntUtil.IsPower2(b_abs)) { MultiPrecision <N> a_power2 = Ldexp(a, -UIntUtil.Power2(b_abs)); return(b >= 0 ? a_power2 : Neg(a_power2)); } int expands = BigUInt <Plus4 <N> > .Length - BigUInt <N> .Length; BigUInt <Plus4 <N> > acc = new(a.mantissa.Value.ToArray(), expands); acc /= b_abs; int lzc = acc.LeadingZeroCount; acc <<= lzc; Int64 exponent = a.Exponent - lzc; Sign sign = (a.Sign == UIntUtil.Sign(b)) ? Sign.Plus : Sign.Minus; bool round = acc[expands - 1] > UIntUtil.UInt32Round; Mantissa <N> mantissa = new(acc.Value.Skip(expands).ToArray(), enable_clone : false); return(new MultiPrecision <N>(sign, exponent, mantissa, round)); }
public static MultiPrecision <N> Sub(MultiPrecision <N> a, long b) { if (b == 0) { return(a); } if (a.IsNaN) { return(NaN); } if (a.IsZero) { return(Neg(b)); } if (!a.IsFinite) { return(a); } UInt64 b_abs = UIntUtil.Abs(b); if (a.Sign == UIntUtil.Sign(b)) { (Mantissa <N> n, Int64 exponent, bool round, Sign sign) = Diff(a.mantissa, b_abs, -a.Exponent); return(new MultiPrecision <N>( (a.Sign == Sign.Plus ^ sign == Sign.Plus) ? Sign.Minus : Sign.Plus, exponent + a.Exponent, n, round)); } else { (Mantissa <N> n, Int64 exponent, bool round) = Add(a.mantissa, b_abs, -a.Exponent); return(new MultiPrecision <N>(a.Sign, exponent + a.Exponent, n, round)); } }