MCPcopy Create free account
hub / github.com/LUX-Core/lux / DivideThreeWordsByTwo

Function DivideThreeWordsByTwo

src/cryptopp/integer.cpp:413–453  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

411// do a 3 word by 2 word divide, returns quotient and leaves remainder in A
412template <class S, class D>
413S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL)
414{
415 CRYPTOPP_UNUSED(dummy);
416
417 // Assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S
418 CRYPTOPP_ASSERT(A[2] < B1 || (A[2]==B1 && A[1] < B0));
419
420 // estimate the quotient: do a 2 S by 1 S divide.
421 // Profiling tells us the original second case was dominant, so it was promoted to the first If statement.
422 // The code change occurred at Commit dc99266599a0e72d.
423
424 S Q; bool pre = (S(B1+1) == 0);
425 if (B1 > 0 && !pre)
426 Q = D(A[1], A[2]) / S(B1+1);
427 else if (pre)
428 Q = A[2];
429 else
430 Q = D(A[0], A[1]) / B0;
431
432 // now subtract Q*B from A
433 D p = D::Multiply(B0, Q);
434 D u = (D) A[0] - p.GetLowHalf();
435 A[0] = u.GetLowHalf();
436 u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q);
437 A[1] = u.GetLowHalf();
438 A[2] += u.GetHighHalf();
439
440 // Q <= actual quotient, so fix it
441 while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0))
442 {
443 u = (D) A[0] - B0;
444 A[0] = u.GetLowHalf();
445 u = (D) A[1] - B1 - u.GetHighHalfAsBorrow();
446 A[1] = u.GetLowHalf();
447 A[2] += u.GetHighHalf();
448 Q++;
449 CRYPTOPP_ASSERT(Q); // shouldn't overflow
450 }
451
452 return Q;
453}
454
455// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1
456template <class S, class D>

Callers

nothing calls this directly

Calls 4

GetLowHalfMethod · 0.80
GetHighHalfMethod · 0.80
GetHighHalfAsBorrowMethod · 0.80
MultiplyFunction · 0.70

Tested by

no test coverage detected