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)); } } }
// 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)); } } }