kaenan

Pseudocode BigNums

Nov 12th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.72 KB | None | 0 0
  1. Intreg arrmultiply(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
  2. {
  3.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  4.     Intreg signA <- find_sign(termA)
  5.     Intreg signB <- find_sign(termB)
  6.  
  7.     // Skip sign OR set sign to 1 if no sign was found.
  8.     Intreg termA_1st_digit, termB_1st_digit
  9.  
  10.     termA_1st_digit <- termB_1st_digit <- 0
  11.  
  12.     daca (signA) {
  13.         termA_1st_digit++
  14.     }
  15.     altfel {
  16.         signA <- 1
  17.     }
  18.  
  19.     daca (signB) {
  20.         termB_1st_digit++
  21.     }
  22.     altfel {
  23.         signB <- 1
  24.     }
  25.  
  26.     /* 0 * ... */
  27.     daca ((lenA - termA_1st_digit) = 1 AND termA[termA_1st_digit] = 0) {
  28.         termB[0] <- 0
  29.         returneaza 1
  30.     }
  31.    
  32.     /* ... * 0 */
  33.     daca ((lenB - termB_1st_digit) = 1 AND termB[termB_1st_digit] = 0) {
  34.         termB[0] <- 0
  35.         returneaza 1
  36.     }
  37.  
  38.     /* Get result sign. */
  39.     Intreg result_sign <- signA * signB
  40.  
  41.     multiplicand:Interg[lenA + lenB + 1]
  42.  
  43.     multiplier:Intreg[MAX(lenA, lenB]
  44.  
  45.     Intreg lenM, lenm
  46.  
  47.     /* Copy the "shorter" number into multiplier (for less shifts of the multiplicand). */
  48.  
  49.     daca (lenA > lenB OR lenA = lenB) {
  50.         lenM <- arrncpy(multiplicand, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit)
  51.  
  52.         lenm <- arrncpy(multiplier, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit)
  53.     }
  54.  
  55.     altfel daca (lenB > lenA) {
  56.         lenM <- arrncpy(multiplicand, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit)
  57.  
  58.         lenm <- arrncpy(multiplier, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit)
  59.     }
  60.  
  61.     /* Make the result (termB) 0. */
  62.     Intreg result_len
  63.     result_len <- lenA + lenB + 1
  64.  
  65.     pentru i=0,result_len-1,1 {
  66.         termB[i] <- 0
  67.     }
  68.  
  69.     Intreg jRes
  70.     jRes <- result_len - 1
  71.  
  72.     Intreg sum, transport
  73.     transport <- 0
  74.  
  75.     pentru i=lenm-1,0,-1 {
  76.  
  77.         prentru j=lenM-1,0,-1 {
  78.  
  79.             /* Multiply and do the sum. */
  80.             sum <-  (multiplier[i] * multiplicand[j]) + termB[jRes] + transport
  81.  
  82.             /* Get the rest. */
  83.             termB[jRes] <- (sum % base)
  84.  
  85.             /* Get the transport. */
  86.             transport <- (sum - termB[jRes]) / base
  87.  
  88.             jRes--
  89.         }
  90.  
  91.         daca (transport) {
  92.             termB[jRes] <- transport
  93.             transport <- 0
  94.         }
  95.  
  96.         jRes <- result_len - 1
  97.  
  98.         /* abc -> abc0 -> abc00 -> abc000 -> ...*/
  99.         lenM <- arrnshift(multiplicand, lenM, lenM, 1)
  100.     }
  101.  
  102.     /* Count the number of insegnificant zeors. */
  103.     int offset <- 0
  104.  
  105.     while (offset < result_len AND !termB[offset]) {
  106.         offset++
  107.     }
  108.  
  109.     /* Set sign. */
  110.     daca (result_sign <-= -1) {
  111.         termB[0] <- '-'
  112.         termB_1st_digit <- 1
  113.         offset--
  114.     }
  115.     altfel {
  116.         termB_1st_digit <- 0
  117.     }
  118.  
  119.     /* Delete insegnificant zeros, if any. */
  120.     lenB <- arrnshift(termB, result_len, termB_1st_digit, -offset)
  121.  
  122.     returneaza lenB
  123. }
  124.  
  125.  
  126. Intreg arrsub(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
  127. {
  128.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  129.     Intreg signA <- find_sign(termA)
  130.     Intreg signB <- find_sign(termB)
  131.  
  132.     // Skip sign OR set sign to 1 if no sign was found.
  133.     Intreg termA_1st_digit, termB_1st_digit
  134.     termA_1st_digit <- termB_1st_digit <- 0
  135.  
  136.     daca (signA) {
  137.         termA_1st_digit++
  138.     }
  139.     altfel {
  140.         signA <- 1
  141.     }
  142.  
  143.     daca (signB) {
  144.         termB_1st_digit++
  145.     }
  146.     altfel {
  147.         signB <- 1
  148.     }
  149.  
  150.     /* Find the order relation between termA and termB. */
  151.     Intreg order <- arrnumber_cmp(termA, termB, lenA, lenB)
  152.  
  153.     //    -a - b = - (a + b)                  a - -b = a + b
  154.     daca ( (signA = -1) AND (signB = 1) ) OR ( (signA = 1) AND (signB = -1) ) {
  155.         daca (signA = -1) {
  156.  
  157.             daca (termB_1st_digit = 0) {
  158.                 lenB <- arrnshift(termB, lenB, termB_1st_digit, 1)
  159.             }
  160.  
  161.             termB[0] <- '-'
  162.         }
  163.         altfel {
  164.             arrnshift(termB, lenB, 0, -1)
  165.             lenB--
  166.         }
  167.  
  168.         return arradd(termA, termB, lenA, lenB, base)
  169.     }
  170.  
  171.     //    -a - (-b) = -a + b
  172.     altfel daca (signB = -1) {
  173.         signB <- 1
  174.     }
  175.  
  176.     // The remaining calculation: a - b = a + (-b)
  177.     altfel {
  178.         signB <- -1
  179.     }
  180.  
  181.  
  182.     /* So there's either (-a + b) OR (a + (-b)) to calculate */
  183.  
  184.  
  185.     /*[Obs] The next statemates make sure that the smaller number is the negative number
  186.      * and if any signs are changed, set result_sign accordingly.
  187.      */
  188.     Intreg result_sign <- 0
  189.  
  190.  
  191.     /* Subbing numbers equal in module => 0. */
  192.     daca (!order) {
  193.         termB[0] <- 0
  194.         return 1
  195.     }
  196.  
  197.     /*If a > b AND -a + b to calculate; then flip signs: a + (-b). */
  198.     altfel daca (order > 0 AND (signA = -1)) {
  199.         result_sign <- signA  // Set result_sign <- sign of the greater number (a > b).
  200.  
  201.         signA <- 1
  202.         signB <- -1
  203.  
  204.     }
  205.     /*Elif a < b AND a + (-b) to calculate; then flip signs: -a + b */
  206.     altfel daca (order < 0 AND (signB = -1)) {
  207.         result_sign <- signB  // Set result_sign <- sign of the greater number (b > a).
  208.  
  209.         signA <- -1
  210.         signB <- 1
  211.     }
  212.  
  213.     /* If termB (which will store the result) is smaller than termA. */
  214.     daca (
  215.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  216.         )
  217.     {
  218.         /* Shift termB, starting at the first digit. */
  219.         lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
  220.     }
  221.  
  222.  
  223.     /* Operate */
  224.     Intreg iA, jB
  225.  
  226.     iA <- lenA - 1
  227.     jB <- lenB - 1
  228.  
  229.     Intreg sum
  230.     sum <- 0
  231.  
  232.  
  233.     /* Right to left do signed addition. */
  234.     cat timp (
  235.         iA >= termA_1st_digit AND
  236.         jB >= termB_1st_digit
  237.         )
  238.     {
  239.         sum <- termA[iA] * signA + termB[jB] * signB
  240.  
  241.         daca (sum < 0) {
  242.             // Borrow from the positive number.
  243.             daca (signA = 1) {
  244.                 sum += arrborrow(termA, iA, base)
  245.             }
  246.             altfel {
  247.                 sum += arrborrow(termB, jB, base)
  248.             }
  249.  
  250.         }
  251.  
  252.         termB[jB] <- sum
  253.  
  254.         iA-- jB--;
  255.     }
  256.    
  257.     /* Count insegnificant zeros. */
  258.     Intreg offset <- termB_1st_digit
  259.    
  260.     cat timp (offset < lenB AND !termB[offset]) {
  261.         offset++
  262.     }
  263.  
  264.     offset -= termB_1st_digit
  265.  
  266.     /* Delete insegnificant zeros, if any. */
  267.     lenB <- arrnshift(termB, lenB, termB_1st_digit, -offset)
  268.    
  269.  
  270.     /* If signs were changed apply result_sign. */
  271.     daca (result_sign = -1) {
  272.         daca (termB_1st_digit > 0) {
  273.             termB[0] <- '-'
  274.         }
  275.         altfel {
  276.             lenB <- arrnfill(termB, lenB, 0, 1, '-')
  277.         }
  278.     }
  279.     altfel daca (termB_1st_digit > 0) { // (Pozitive result) If termB has sign remove it.
  280.         lenB <- arrnshift(termB, lenB, 0, -1)
  281.     }
  282.  
  283.  
  284.     return lenB
  285. }
  286.  
  287.  
  288. Intreg arrborrow(Intreg arr[], Intreg poz, Intreg base)
  289. {
  290.     Intreg i, found
  291.  
  292.     i <- poz - 1 // The next position to look for borrow.
  293.     found <- 0   // Whether there is "lender" to borrow from.
  294.  
  295.     /* Find "lender" right to left and borrow, if possible. */
  296.     while ( i >= 0 AND !found;) {
  297.         daca (arr[i] AND arr[i] < base) {
  298.  
  299.             arr[i]--
  300.             found <- 1
  301.         }
  302.  
  303.         i--
  304.     }
  305.  
  306.     /* No "lender". */
  307.     daca (!found) {
  308.         return -1
  309.     }
  310.  
  311.     /* Else lender was found, and borrowed from "it". */
  312.  
  313.     /* Distribute the borrow, left to right. */
  314.     for (i += 2; i < poz; i++) {
  315.         arr[i] += base - 1
  316.     }
  317.  
  318.     /* The borrower gets full unit. */
  319.     arr[i] += base
  320.  
  321.     return base
  322. }
  323.  
  324. Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
  325. {
  326.  
  327.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  328.     Intreg signA <- find_sign(termA)
  329.     Intreg signB <- find_sign(termB)
  330.  
  331.     // Skip sign OR set sign to 1 if no sign was found.
  332.     Intreg termA_1st_digit, termB_1st_digit
  333.     termA_1st_digit <- termB_1st_digit <- 0
  334.  
  335.     daca (signA) {
  336.         termA_1st_digit++
  337.     }
  338.     altfel {
  339.         signA <- 1
  340.     }
  341.  
  342.     daca (signB) {
  343.         termB_1st_digit++
  344.     }
  345.     altfel {
  346.         signB <- 1
  347.     }
  348.  
  349.  
  350.     /* If signs are different, return call arrsub. */
  351.     daca (signA != signB) {
  352.  
  353.         daca (signA = -1) {
  354.             /* -a + b = -a - (-b) */
  355.             lenB <- arrnfill(termB, lenB, 0, 1, '-')
  356.  
  357.             returneaza arrsub(termA, termB, lenA, lenB, base)
  358.         }
  359.  
  360.         altfel {
  361.             /* a + (- b) = a - b */
  362.             lenB = arrnshift(termB, lenB, 0, -1)
  363.  
  364.             returneaza arrsub(termA, termB, lenA, lenB, base)
  365.         }
  366.     }
  367.  
  368.     /* If termB (which will store the result) is smaller than termA. */
  369.     daca (
  370.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  371.         )
  372.     {
  373.         /* Shift termB, starting at the first digit. */
  374.         lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
  375.     }
  376.  
  377.  
  378.     /* Operate */
  379.  
  380.     Intreg iA, jB
  381.  
  382.     /* Used for iterating. */
  383.     iA <- lenA - 1
  384.     jB <- lenB - 1
  385.  
  386.     Intreg sum, transport
  387.     sum <- transport <- 0
  388.  
  389.  
  390.     /* Right to left add. */
  391.     while (
  392.         iA >= termA_1st_digit AND
  393.         jB >= termB_1st_digit
  394.         )
  395.     {
  396.         sum <- termA[iA] + termB[jB] + transport
  397.  
  398.         termB[jB] <- sum % base
  399.         transport <- (sum >= base) ? 1 : 0
  400.  
  401.         iA-- jB--;
  402.     }
  403.  
  404.  
  405.     /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
  406.     while (jB >= termB_1st_digit AND transport) {
  407.         sum <- termB[jB] + transport
  408.  
  409.         termB[jB] <- sum % base
  410.         transport <- (sum >= base) ? 1 : 0
  411.  
  412.         jB--
  413.     }
  414.  
  415.     /* If there's transport: shift by 1, starting at the index of 1st_digit
  416.     * and fill new position with 1 (transport)
  417.     */
  418.     daca (transport) {
  419.         arrnfill(termB, lenB, termB_1st_digit, 1, transport)
  420.         lenB++
  421.     }
  422.  
  423.     returneaza lenB
  424. }
  425.  
  426. Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
  427. {
  428.  
  429.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  430.     Intreg signA <- find_sign(termA)
  431.     Intreg signB <- find_sign(termB)
  432.  
  433.     // Skip sign OR set sign to 1 if no sign was found.
  434.     Intreg termA_1st_digit, termB_1st_digit
  435.     termA_1st_digit <- termB_1st_digit <- 0
  436.  
  437.     daca (signA) {
  438.         termA_1st_digit++
  439.     }
  440.     altfel {
  441.         signA <- 1
  442.     }
  443.  
  444.     daca (signB) {
  445.         termB_1st_digit++
  446.     }
  447.     altfel {
  448.         signB <- 1
  449.     }
  450.  
  451.  
  452.     /* If signs are different, return call arrsub. */
  453.     daca (signA != signB) {
  454.  
  455.         daca (signA = -1) {
  456.             /* -a + b = -a - (-b) */
  457.             lenB <- arrnfill(termB, lenB, 0, 1, '-')
  458.  
  459.             returneaza arrsub(termA, termB, lenA, lenB, base)
  460.         }
  461.  
  462.         altfel {
  463.             /* a + (- b) = a - b */
  464.             lenB = arrnshift(termB, lenB, 0, -1)
  465.  
  466.             returneaza arrsub(termA, termB, lenA, lenB, base)
  467.         }
  468.     }
  469.  
  470.     /* If termB (which will store the result) is smaller than termA. */
  471.     daca (
  472.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  473.         )
  474.     {
  475.         /* Shift termB, starting at the first digit. */
  476.         lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
  477.     }
  478.  
  479.  
  480.     /* Operate */
  481.  
  482.     Intreg iA, jB
  483.  
  484.     /* Used for iterating. */
  485.     iA <- lenA - 1
  486.     jB <- lenB - 1
  487.  
  488.     Intreg sum, transport
  489.     sum <- transport <- 0
  490.  
  491.  
  492.     /* Right to left add. */
  493.     while (
  494.         iA >= termA_1st_digit AND
  495.         jB >= termB_1st_digit
  496.         )
  497.     {
  498.         sum <- termA[iA] + termB[jB] + transport
  499.  
  500.         termB[jB] <- sum % base
  501.         transport <- (sum >= base) ? 1 : 0
  502.  
  503.         iA-- jB--;
  504.     }
  505.  
  506.  
  507.     /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
  508.     while (jB >= termB_1st_digit AND transport) {
  509.         sum <- termB[jB] + transport
  510.  
  511.         termB[jB] <- sum % base
  512.         transport <- (sum >= base) ? 1 : 0
  513.  
  514.         jB--
  515.     }
  516.  
  517.     /* If there's transport: shift by 1, starting at the index of 1st_digit
  518.     * and fill new position with 1 (transport)
  519.     */
  520.     daca (transport) {
  521.         arrnfill(termB, lenB, termB_1st_digit, 1, transport)
  522.         lenB++
  523.     }
  524.  
  525.     returneaza lenB
  526. }
  527.  
  528. Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
  529. {
  530.  
  531.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  532.     Intreg signA <- find_sign(termA)
  533.     Intreg signB <- find_sign(termB)
  534.  
  535.     // Skip sign OR set sign to 1 if no sign was found.
  536.     Intreg termA_1st_digit, termB_1st_digit
  537.     termA_1st_digit <- termB_1st_digit <- 0
  538.  
  539.     daca (signA) {
  540.         termA_1st_digit++
  541.     }
  542.     altfel {
  543.         signA <- 1
  544.     }
  545.  
  546.     daca (signB) {
  547.         termB_1st_digit++
  548.     }
  549.     altfel {
  550.         signB <- 1
  551.     }
  552.  
  553.  
  554.     /* If signs are different, return call arrsub. */
  555.     daca (signA != signB) {
  556.  
  557.         daca (signA = -1) {
  558.             /* -a + b = -a - (-b) */
  559.             lenB <- arrnfill(termB, lenB, 0, 1, '-')
  560.  
  561.             returneaza arrsub(termA, termB, lenA, lenB, base)
  562.         }
  563.  
  564.         altfel {
  565.             /* a + (- b) = a - b */
  566.             lenB = arrnshift(termB, lenB, 0, -1)
  567.  
  568.             returneaza arrsub(termA, termB, lenA, lenB, base)
  569.         }
  570.     }
  571.  
  572.     /* If termB (which will store the result) is smaller than termA. */
  573.     daca (
  574.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  575.         )
  576.     {
  577.         /* Shift termB, starting at the first digit. */
  578.         lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
  579.     }
  580.  
  581.  
  582.     /* Operate */
  583.  
  584.     Intreg iA, jB
  585.  
  586.     /* Used for iterating. */
  587.     iA <- lenA - 1
  588.     jB <- lenB - 1
  589.  
  590.     Intreg sum, transport
  591.     sum <- transport <- 0
  592.  
  593.  
  594.     /* Right to left add. */
  595.     while (
  596.         iA >= termA_1st_digit AND
  597.         jB >= termB_1st_digit
  598.         )
  599.     {
  600.         sum <- termA[iA] + termB[jB] + transport
  601.  
  602.         termB[jB] <- sum % base
  603.         transport <- (sum >= base) ? 1 : 0
  604.  
  605.         iA-- jB--;
  606.     }
  607.  
  608.  
  609.     /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
  610.     while (jB >= termB_1st_digit AND transport) {
  611.         sum <- termB[jB] + transport
  612.  
  613.         termB[jB] <- sum % base
  614.         transport <- (sum >= base) ? 1 : 0
  615.  
  616.         jB--
  617.     }
  618.  
  619.     /* If there's transport: shift by 1, starting at the index of 1st_digit
  620.     * and fill new position with 1 (transport)
  621.     */
  622.     daca (transport) {
  623.         arrnfill(termB, lenB, termB_1st_digit, 1, transport)
  624.         lenB++
  625.     }
  626.  
  627.     returneaza lenB
  628. }
  629.  
  630. Intreg find_sign(Intreg term[])
  631. {
  632.     daca (term[0] = '-') {
  633.         returneaza -1
  634.     }
  635.     altfel daca (term[0] = '+') {
  636.         return 1
  637.     }
  638.  
  639.     // no sign
  640.     returneaza 0
  641. }
Add Comment
Please, Sign In to add comment