static int FindDigit(LongIntegerNumber divident, IList<int> divisorParts) { LongIntegerNumber divisor = new LongIntegerNumber(divisorParts, false); if(divident == Zero || divisor > divident) { return 0; } int dividentPart = ((divident.parts.Count == divisor.parts.Count) ? divident.parts.Last() : divident.parts.Last() * BaseFull + divident.parts[divident.parts.Count - 2]); int divisorPart = divisor.parts.Last(); int lowDigit = Div(dividentPart, divisorPart + 1); //TODO optimize - no need to add 1 if divisor has zeros at the end #if DEBUG int checkCount = 0; #endif int topDigit = Div(dividentPart + 1, divisorPart); int digit = Bisect(lowDigit, topDigit); while(true) { Number mult = divisor.Multiply(new LongIntegerNumber(new int[] { digit }, false)); LongIntegerNumber remain = (LongIntegerNumber)divident.Subtract(mult); if(remain.isNegative) { #if DEBUG checkCount++; #endif topDigit = digit; digit = Bisect(lowDigit, topDigit); continue; } int comparisonResult = remain.Compare(divisor); if(comparisonResult >= 0) { #if DEBUG checkCount++; #endif lowDigit = digit + 1; digit = Bisect(lowDigit, topDigit); continue; } break; } #if DEBUG if(checkCount > 15) throw new InvalidOperationException(); #endif return digit; }