MCPcopy Create free account
hub / github.com/numpy/numpy / BigInt_DivideWithRemainder_MaxQuotient9

Function BigInt_DivideWithRemainder_MaxQuotient9

numpy/core/src/multiarray/dragon4.c:898–998  ·  view source on GitHub ↗

* This function will divide two large numbers under the assumption that the * result is within the range [0,10) and the input numbers have been shifted * to satisfy: * - The highest block of the divisor is greater than or equal to 8 such that * there is enough precision to make an accurate first guess at the quotient. * - The highest block of the divisor is less than the maximum value on an

Source from the content-addressed store, hash-verified

896 * dividend is updated to be the remainder and the quotient is returned.
897 */
898static npy_uint32
899BigInt_DivideWithRemainder_MaxQuotient9(BigInt *dividend, const BigInt *divisor)
900{
901 npy_uint32 length, quotient;
902 const npy_uint32 *finalDivisorBlock;
903 npy_uint32 *finalDividendBlock;
904
905 /*
906 * Check that the divisor has been correctly shifted into range and that it
907 * is not smaller than the dividend in length.
908 */
909 DEBUG_ASSERT(!divisor->length == 0 &&
910 divisor->blocks[divisor->length-1] >= 8 &&
911 divisor->blocks[divisor->length-1] < bitmask_u64(32) &&
912 dividend->length <= divisor->length);
913
914 /*
915 * If the dividend is smaller than the divisor, the quotient is zero and the
916 * divisor is already the remainder.
917 */
918 length = divisor->length;
919 if (dividend->length < divisor->length) {
920 return 0;
921 }
922
923 finalDivisorBlock = divisor->blocks + length - 1;
924 finalDividendBlock = dividend->blocks + length - 1;
925
926 /*
927 * Compute an estimated quotient based on the high block value. This will
928 * either match the actual quotient or undershoot by one.
929 */
930 quotient = *finalDividendBlock / (*finalDivisorBlock + 1);
931 DEBUG_ASSERT(quotient <= 9);
932
933 /* Divide out the estimated quotient */
934 if (quotient != 0) {
935 /* dividend = dividend - divisor*quotient */
936 const npy_uint32 *divisorCur = divisor->blocks;
937 npy_uint32 *dividendCur = dividend->blocks;
938
939 npy_uint64 borrow = 0;
940 npy_uint64 carry = 0;
941 do {
942 npy_uint64 difference, product;
943
944 product = (npy_uint64)*divisorCur * (npy_uint64)quotient + carry;
945 carry = product >> 32;
946
947 difference = (npy_uint64)*dividendCur
948 - (product & bitmask_u64(32)) - borrow;
949 borrow = (difference >> 32) & 1;
950
951 *dividendCur = difference & bitmask_u64(32);
952
953 ++divisorCur;
954 ++dividendCur;
955 } while(divisorCur <= finalDivisorBlock);

Callers 1

Dragon4Function · 0.85

Calls 2

bitmask_u64Function · 0.85
BigInt_CompareFunction · 0.85

Tested by

no test coverage detected