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

Function BigInt_Add

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

result = lhs + rhs */

Source from the content-addressed store, hash-verified

317
318/* result = lhs + rhs */
319static void
320BigInt_Add(BigInt *result, const BigInt *lhs, const BigInt *rhs)
321{
322 /* determine which operand has the smaller length */
323 const BigInt *large, *small;
324 npy_uint64 carry = 0;
325 const npy_uint32 *largeCur, *smallCur, *largeEnd, *smallEnd;
326 npy_uint32 *resultCur;
327
328 if (lhs->length < rhs->length) {
329 small = lhs;
330 large = rhs;
331 }
332 else {
333 small = rhs;
334 large = lhs;
335 }
336
337 /* The output will be at least as long as the largest input */
338 result->length = large->length;
339
340 /* Add each block and add carry the overflow to the next block */
341 largeCur = large->blocks;
342 largeEnd = largeCur + large->length;
343 smallCur = small->blocks;
344 smallEnd = smallCur + small->length;
345 resultCur = result->blocks;
346 while (smallCur != smallEnd) {
347 npy_uint64 sum = carry + (npy_uint64)(*largeCur) +
348 (npy_uint64)(*smallCur);
349 carry = sum >> 32;
350 *resultCur = sum & bitmask_u64(32);
351 ++largeCur;
352 ++smallCur;
353 ++resultCur;
354 }
355
356 /* Add the carry to any blocks that only exist in the large operand */
357 while (largeCur != largeEnd) {
358 npy_uint64 sum = carry + (npy_uint64)(*largeCur);
359 carry = sum >> 32;
360 (*resultCur) = sum & bitmask_u64(32);
361 ++largeCur;
362 ++resultCur;
363 }
364
365 /* If there's still a carry, append a new block */
366 if (carry != 0) {
367 DEBUG_ASSERT(carry == 1);
368 DEBUG_ASSERT((npy_uint32)(resultCur - result->blocks) ==
369 large->length && (large->length < c_BigInt_MaxBlocks));
370 *resultCur = 1;
371 result->length = large->length + 1;
372 }
373 else {
374 result->length = large->length;
375 }
376}

Callers 1

Dragon4Function · 0.85

Calls 1

bitmask_u64Function · 0.85

Tested by

no test coverage detected