* result = lhs * rhs */
| 379 | * result = lhs * rhs |
| 380 | */ |
| 381 | static void |
| 382 | BigInt_Multiply(BigInt *result, const BigInt *lhs, const BigInt *rhs) |
| 383 | { |
| 384 | const BigInt *large; |
| 385 | const BigInt *small; |
| 386 | npy_uint32 maxResultLen; |
| 387 | npy_uint32 *cur, *end, *resultStart; |
| 388 | const npy_uint32 *smallCur; |
| 389 | |
| 390 | DEBUG_ASSERT(result != lhs && result != rhs); |
| 391 | |
| 392 | /* determine which operand has the smaller length */ |
| 393 | if (lhs->length < rhs->length) { |
| 394 | small = lhs; |
| 395 | large = rhs; |
| 396 | } |
| 397 | else { |
| 398 | small = rhs; |
| 399 | large = lhs; |
| 400 | } |
| 401 | |
| 402 | /* set the maximum possible result length */ |
| 403 | maxResultLen = large->length + small->length; |
| 404 | DEBUG_ASSERT(maxResultLen <= c_BigInt_MaxBlocks); |
| 405 | |
| 406 | /* clear the result data */ |
| 407 | for (cur = result->blocks, end = cur + maxResultLen; cur != end; ++cur) { |
| 408 | *cur = 0; |
| 409 | } |
| 410 | |
| 411 | /* perform standard long multiplication for each small block */ |
| 412 | resultStart = result->blocks; |
| 413 | for (smallCur = small->blocks; |
| 414 | smallCur != small->blocks + small->length; |
| 415 | ++smallCur, ++resultStart) { |
| 416 | /* |
| 417 | * if non-zero, multiply against all the large blocks and add into the |
| 418 | * result |
| 419 | */ |
| 420 | const npy_uint32 multiplier = *smallCur; |
| 421 | if (multiplier != 0) { |
| 422 | const npy_uint32 *largeCur = large->blocks; |
| 423 | npy_uint32 *resultCur = resultStart; |
| 424 | npy_uint64 carry = 0; |
| 425 | do { |
| 426 | npy_uint64 product = (*resultCur) + |
| 427 | (*largeCur)*(npy_uint64)multiplier + carry; |
| 428 | carry = product >> 32; |
| 429 | *resultCur = product & bitmask_u64(32); |
| 430 | ++largeCur; |
| 431 | ++resultCur; |
| 432 | } while(largeCur != large->blocks + large->length); |
| 433 | |
| 434 | DEBUG_ASSERT(resultCur < result->blocks + maxResultLen); |
| 435 | *resultCur = (npy_uint32)(carry & bitmask_u64(32)); |
| 436 | } |
| 437 | } |
| 438 |
no test coverage detected