public static BigDecimal DividePrimitiveLongs(long scaledDividend, long scaledDivisor, int scale,
                                                      RoundingMode roundingMode)
        {
            long quotient  = scaledDividend / scaledDivisor;
            long remainder = scaledDividend % scaledDivisor;
            int  sign      = System.Math.Sign(scaledDividend) * System.Math.Sign(scaledDivisor);

            if (remainder != 0)
            {
                // Checking if:  remainder * 2 >= scaledDivisor
                int compRem;                 // 'compare to remainder'
                compRem = BigDecimal.LongCompareTo(System.Math.Abs(remainder) << 1, System.Math.Abs(scaledDivisor));
                // To look if there is a carry
                quotient += BigDecimal.RoundingBehavior(((int)quotient) & 1, sign * (5 + compRem), roundingMode);
            }
            // Constructing the result with the appropriate unscaled value
            return(BigDecimal.Create(quotient, scale));
        }
        public static BigDecimal DivideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale,
                                                   RoundingMode roundingMode)
        {
            BigInteger remainder;
            BigInteger quotient = BigMath.DivideAndRemainder(scaledDividend, scaledDivisor, out remainder);

            if (remainder.Sign == 0)
            {
                return(new BigDecimal(quotient, scale));
            }
            int sign = scaledDividend.Sign * scaledDivisor.Sign;
            int compRem;             // 'compare to remainder'

            if (scaledDivisor.BitLength < 63)
            {
                // 63 in order to avoid out of long after <<1
                long rem     = remainder.ToInt64();
                long divisor = scaledDivisor.ToInt64();
                compRem = BigDecimal.LongCompareTo(System.Math.Abs(rem) << 1, System.Math.Abs(divisor));
                // To look if there is a carry
                compRem = BigDecimal.RoundingBehavior(BigInteger.TestBit(quotient, 0) ? 1 : 0,
                                                      sign * (5 + compRem), roundingMode);
            }
            else
            {
                // Checking if:  remainder * 2 >= scaledDivisor
                compRem = BigMath.Abs(remainder).ShiftLeftOneBit().CompareTo(BigMath.Abs(scaledDivisor));
                compRem = BigDecimal.RoundingBehavior(BigInteger.TestBit(quotient, 0) ? 1 : 0,
                                                      sign * (5 + compRem), roundingMode);
            }
            if (compRem != 0)
            {
                if (quotient.BitLength < 63)
                {
                    return(BigDecimal.Create(quotient.ToInt64() + compRem, scale));
                }
                quotient += BigInteger.FromInt64(compRem);
                return(new BigDecimal(quotient, scale));
            }
            // Constructing the result with the appropriate unscaled value
            return(new BigDecimal(quotient, scale));
        }