public static ULong DivideFloat(ULong lowDividend, ULong highDividend, ULong lowDivisor)
        {
            const ULong highDivisor = 1u;

            unchecked {
                ULong lowProduct;
                ULong highProduct;
                ULong lowResult;
                ULong t;
                {
                    var cc = ULong_Misc.BitSizeAsIntUnchecked - 1;
                    t         = highDivisor << cc;
                    lowResult = MathEx.BigDivInternal(
                        lowDividend >> (ULong_Misc.BitSizeAsIntUnchecked - cc) | (highDividend << cc),
                        highDividend >> (ULong_Misc.BitSizeAsIntUnchecked - cc),
                        (lowDivisor >> (ULong_Misc.BitSizeAsIntUnchecked - cc)) | t);
                }
                t            = lowResult * highDivisor;
                lowProduct   = MathEx.BigMul(lowResult, lowDivisor, out highProduct);
                highProduct += t;
                if (t > highProduct || highProduct > highDividend)
                {
                    goto L_0001;
                }
                if (highDividend > highProduct || lowProduct <= lowDividend)
                {
                    goto L_0002;
                }
L_0001:
                --lowResult;
L_0002:
                return(lowResult);
            }
        }
        // 91.3 Cyc (special input set test6)
        public static ULong Divide(ULong lowDividend, ULong highDividend, ULong lowDivisor, ULong highDivisor, out ULong highResult)
        {
            unchecked {
                if (0u != highDivisor)
                {
                    if (0 <= (Long)highDivisor)
                    {
                        ULong lowProduct;
                        ULong highProduct;
                        ULong lowResult;
                        ULong t;
                        {
                            var cc = 0;
                            // CountLeadingZeros
                            // ? using CountLeadingZeros is better or not?
                            t = highDivisor;
                            for (; 0 <= (Long)t; t <<= 1)
                            {
                                ++cc;
                            }
                            lowResult = MathEx.BigDivInternal(
                                lowDividend >> (ULong_Misc.BitSizeAsIntUnchecked - cc) | (highDividend << cc),
                                highDividend >> (ULong_Misc.BitSizeAsIntUnchecked - cc),
                                (lowDivisor >> (ULong_Misc.BitSizeAsIntUnchecked - cc)) | t);
                        }
                        t            = lowResult * highDivisor;
                        lowProduct   = MathEx.BigMul(lowResult, lowDivisor, out highProduct);
                        highProduct += t;
                        if (t > highProduct || highProduct > highDividend)
                        {
                            goto L_0001;
                        }
                        if (highDividend > highProduct || lowProduct <= lowDividend)
                        {
                            goto L_0002;
                        }
L_0001:
                        --lowResult;
                        highProduct = ((lowDivisor > lowProduct) ? (highProduct - highDivisor - 1u) : (highProduct - highDivisor));
                        lowProduct -= lowDivisor;
L_0002:
                        highResult = 0u;
                        return(lowResult);
                    }
                    else
                    {
                        highResult = 0u;
                        if (highDivisor <= highDividend && (highDivisor != highDividend || lowDivisor <= lowDividend))
                        {
                            return(1u);
                        }
                        else
                        {
                            return(0u);
                        }
                    }
                }
                else
                {
                    ULong t;
                    highResult = Math.DivRem(highDividend, lowDivisor, out t);
                    return(MathEx.BigDivInternal(lowDividend, t, lowDivisor));
                }
            }
        }
コード例 #3
0
        // 109 Cyc (special inpot set test6)
        public static ULong Remainder(ULong lowDividend, ULong highDividend, ULong lowDivisor, ULong highDivisor, out ULong highResult)
        {
            unchecked {
                if (0u != highDivisor)
                {
                    if (0 <= (Long)highDivisor)
                    {
                        ULong lowProduct;
                        ULong highProduct;
                        ULong lowResult;
                        ULong t;
                        {
                            int cc;
#if (NET5_0 || NET6_0 || NET5_0_OR_GREATER)
                            cc = BinaryNumerals.CountLeadingZeros(highDivisor);
                            t  = highDivisor << cc;
#else
                            // CountLeadingZeros
                            // ? using CountLeadingZeros is better or not?
                            cc = 0;
                            t  = highDivisor;
                            for (; 0 <= (Long)t; t <<= 1)
                            {
                                ++cc;
                            }
#endif
                            lowResult = MathEx.BigDivInternal(
                                lowDividend >> (Misc.ULong.BitSize - cc) | (highDividend << cc),
                                highDividend >> (Misc.ULong.BitSize - cc),
                                (lowDivisor >> (Misc.ULong.BitSize - cc)) | t);
                        }
                        t            = lowResult * highDivisor;
                        lowProduct   = MathEx.BigMul(lowResult, lowDivisor, out highProduct);
                        highProduct += t;
                        if (t > highProduct || highProduct > highDividend)
                        {
                            goto L_0001;
                        }
                        if (highDividend > highProduct || lowProduct <= lowDividend)
                        {
                            goto L_0002;
                        }
L_0001:
                        --lowResult;
                        highProduct = ((lowDivisor > lowProduct) ? (highProduct - highDivisor - 1u) : (highProduct - highDivisor));
                        lowProduct -= lowDivisor;
L_0002:
                        highResult = ((lowProduct > lowDividend) ? (highDividend - highProduct - 1u) : (highDividend - highProduct));
                        return(lowDividend - lowProduct);
                    }
                    else
                    {
                        highResult = 0u;
                        if (highDivisor <= highDividend && (highDivisor != highDividend || lowDivisor <= lowDividend))
                        {
                            return(MathEx.SubtractUnchecked(lowDividend, highDividend, lowDivisor, highDivisor, out highResult));
                        }
                        else
                        {
                            highResult = highDividend;
                            return(lowDividend);
                        }
                    }
                }
                else
                {
                    highResult = 0u;
                    return(MathEx.BigRemInternal(lowDividend, highDividend % lowDivisor, lowDivisor));
                }
            }
        }