Advertisement
kaenan

BigNums +,-,*

Nov 12th, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.38 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6. #define NEWLINE std::cout << std::endl
  7.  
  8. #define MAX(x, y) ((x > y) ? x : y)
  9.  
  10. void *ec_realloc(void *ptr, unsigned int size)
  11. {
  12.     void *new_ptr;
  13.  
  14.     new_ptr = realloc(ptr, size);
  15.  
  16.     if (!new_ptr) {
  17.         printf("[Error] ec_realloc(): realloc() returned NULL.");
  18.         exit(-1);
  19.     }
  20.  
  21.     return new_ptr;
  22. }
  23.  
  24. void *ec_malloc(unsigned int size)
  25. {
  26.     return ec_realloc(NULL, size);
  27. }
  28.  
  29.  
  30. /* Returns the char if found in string otherwise returns 0.
  31.  * Dependency of strto_arrnumber
  32.  */
  33. unsigned int strchr_(char *s, char c)
  34. {
  35.     while (*s && *s != c) { s++; }
  36.  
  37.     return *s;
  38. }
  39.  
  40. char *cin_getline()
  41. {
  42.     char *string;
  43.  
  44.     /* i - used for *iterating* over the block s points to. */
  45.     unsigned int i = 0, size = 100;
  46.  
  47.     /* Allocate memory for string */
  48.     string = (char *)ec_malloc(size);
  49.  
  50.     for (
  51.         int c;
  52.         /* *While* c != EOF ^ '\n'. */
  53.         EOF != (c = getchar()) && '\n' != c;
  54.         /* *Insert* c into string. */
  55.         *(string + i) = c, i++
  56.         )
  57.     {
  58.         /* Resize string to fit the current chr ^ more chrs. */
  59.         if (i >= size) {
  60.             string = (char *)ec_realloc(string, (size += 30));
  61.         }
  62.     }
  63.  
  64.     /* Discard unused memory (also needed *if* i == size). */
  65.     string = (char *)ec_realloc(string, i + 1);
  66.  
  67.     /* End string. */
  68.     *(string + i) = '\0';
  69.  
  70.     return string;
  71. }
  72.  
  73. /* Converts a string to array of numbers.
  74.  * Returns null if conversion failed and sets errno_.
  75.  * Ends array with 'E', to be used for calculating length with arrnumber_len.
  76. */
  77. int *strto_arrnumber(const char *string)
  78. {
  79.     if (NULL == string || !*string) {
  80.         printf("[Warning] strto_arrnumber(): Null input.\n");
  81.  
  82.         return NULL;
  83.     }
  84.  
  85.     int *strnumber = (int *)malloc((strlen(string) + 1) * sizeof(int));
  86.  
  87.  
  88.     /* Used for iterating over string. */
  89.     unsigned int strI = 0;
  90.  
  91.     /* Used for forming strnumber. */
  92.     unsigned int numI = 0;
  93.  
  94.  
  95.     char white_space[] = " \n\t";
  96.  
  97.     /* Skip inital white space. */
  98.     while (strchr_(white_space, string[strI])) {
  99.         strI++;
  100.     }
  101.  
  102.     /* Check for sign. */
  103.     if (string[strI] == '-') {
  104.         strnumber[numI++] = string[strI++];
  105.     }
  106.     else if (string[strI] == '+') {
  107.         strI++;
  108.     }
  109.  
  110.  
  111.     /* If input string is null OR if input string contains only a sign (+ or -). */
  112.     if (!string[strI]) {
  113.         printf("[Warning] strto_arrnumber(): Please provide a number: %c[0-9].\n", string[strI - 1]);
  114.  
  115.         return NULL;
  116.     }
  117.  
  118.     /* Ignore insegnificant zeorous */
  119.     while (string[strI + 1] && string[strI] == '0') {
  120.         strI++;
  121.     }
  122.  
  123.     while (string[strI]) {
  124.  
  125.         /* If string[i] is a digit. */
  126.         if (string[strI] >= '0' && string[strI] <= '9') {
  127.             strnumber[numI++] = string[strI++] - '0';
  128.         }
  129.  
  130.         else if (strchr_(white_space, string[strI])) {
  131.  
  132.             /* Ignore white space after the number. */
  133.             while (strchr_(white_space, string[strI])) {
  134.                 strI++;
  135.             }
  136.             if (string[strI]) {
  137.                 printf("[Error] A number has no white space.\n");
  138.  
  139.                 return NULL;
  140.             }
  141.         }
  142.  
  143.         /* string[i] is not a digit. */
  144.         else {
  145.             printf("[Error] Conversion failed: NaN.\n");
  146.  
  147.             return NULL;
  148.         }
  149.     }
  150.  
  151.     strnumber[numI] = 'E';
  152.  
  153.     return strnumber;
  154.  
  155. }
  156.  
  157. /* Work together with the output of strto_arrnumber */
  158. unsigned long arrnumber_len(int *strnumber)
  159. {
  160.     unsigned int len = 0;
  161.  
  162.     while (*strnumber != 'E') {
  163.         len++;
  164.         strnumber++;
  165.     }
  166.  
  167.     return len;
  168. }
  169.  
  170.  
  171. /* Shift array and fill (fill = 0) for positive offset, for negative shift and delete. */
  172. template <class type>
  173. unsigned int arrnshift(type [], unsigned int, unsigned int, int);
  174.  
  175. /* From startingIndex until len, shift array and fill (fill left of startingI that is).
  176.  * If startingIndex is >= len, fill from len until len + offset.
  177. */
  178. template <class type>
  179. unsigned int arrnfill(type [], unsigned int len, unsigned int startingI, int offset, type fill);
  180.  
  181. /* Shift array and delete. If startingI >= len, changes nothing and returns len. */
  182. template <class type>
  183. unsigned int arrnshrink(type [], unsigned int, unsigned int, int);
  184.  
  185.  
  186.  
  187. /* Compares two arrnumbers (their modoule!). */
  188. template <class type>
  189. int arrnumber_cmp(type[], type[], unsigned int, unsigned int);
  190.  
  191.  
  192. /* Copies int arrDest, offset elements from arrStr, begining with the startingI. */
  193. template <class type>
  194. unsigned int arrncpy(type arrDest[], type arrSrc[], unsigned int len, unsigned int startingI, int offset);
  195.  
  196.  
  197.  
  198. /* Add two arrays, in a base < 10. */
  199. unsigned int arradd(int[], int[], unsigned int, unsigned int, unsigned int);
  200.  
  201. /* Sub two arrays, in a base < 10. */
  202. unsigned int arrsub(int[], int[], unsigned int, unsigned int, unsigned int);
  203.  
  204. /* Borrow when subbing. */
  205. int arrborrow(int[], unsigned int, unsigned int);
  206.  
  207. /* Multiply two arrays, in a base < 10. */
  208. unsigned int arrmultiply(int termA[], int termB[], unsigned int lenA, unsigned int lenB, unsigned int base);
  209.  
  210. int init()
  211. {
  212.     char *string;
  213.     string = cin_getline();
  214.  
  215.  
  216.     char *token = NULL;
  217.     char white_space[] = " \t\n";
  218.  
  219.  
  220.     /* LEFT operand */
  221.     int *operandA = NULL;
  222.  
  223.     if (NULL == (token = strtok(string, white_space))) { // get token
  224.         puts("[Error] Please provide a left operand.");
  225.         return -1;
  226.     }
  227.     if (NULL == (operandA = strto_arrnumber(token))) { // token to arrnumber
  228.         printf("[Error] Invalid left operand: \"%s\".\n", token);
  229.         return -1;
  230.     }
  231.  
  232.  
  233.  
  234.     /* Operation */
  235.     char op = 0;
  236.     if (NULL == (token = strtok(NULL, white_space))) { // get token
  237.         puts("[Error] Please provide an operation.");
  238.         return -1;
  239.     }
  240.  
  241.     char operations[] = "+-*";
  242.     if (strlen(token) == 1) {
  243.         if (!(op = strchr_(operations, *token))) {  // get operator
  244.             printf("[Error] Undefined operation: %s\n", token);
  245.             return -1;
  246.         }
  247.     }
  248.     else {
  249.         puts("[Error] Please provide valid operation.");
  250.         return -1;
  251.     }
  252.  
  253.  
  254.  
  255.     /* RIGHT operand */
  256.     int *operandB = NULL;
  257.  
  258.     if (NULL == (token = strtok(NULL, white_space))) { // get token
  259.         puts("[Error] Please provide a right operand.");
  260.         return -1;
  261.     }
  262.     if (NULL == (operandB = strto_arrnumber(token))) { // token to arrnumber
  263.         printf("[Error] Invalid right operand: \"%s\".\n", token);
  264.         return -1;
  265.     }
  266.  
  267.  
  268.     /* Check arity. */
  269.     if (NULL != (token = strtok(NULL, white_space))) {
  270.         return -1;
  271.     }
  272.  
  273.  
  274.     unsigned int lenA, lenB;
  275.     lenA = arrnumber_len(operandA);
  276.     lenB = arrnumber_len(operandB);
  277.  
  278.     /* Make sure the blocks of memory termA and termB point at
  279.      * are big enough for all the operations.
  280.      */
  281.     operandA = (int *)ec_realloc(operandA, (lenA + lenB + 1) * sizeof(int));
  282.     operandB = (int *)ec_realloc(operandB, (lenA + lenB + 1) * sizeof(int));
  283.  
  284.     unsigned int result_len = 0;
  285.     if (op == '+') {
  286.         result_len = arradd(operandA, operandB, lenA, lenB, 10);
  287.     }
  288.     else if (op == '-') {
  289.         result_len = arrsub(operandA, operandB, lenA, lenB, 10);
  290.     }
  291.     else if (op == '*') {
  292.         result_len = arrmultiply(operandA, operandB, lenA, lenB, 10);
  293.     }
  294.  
  295.     /* Print result */
  296.     unsigned int i = 0;
  297.     if (operandB[i] > 10) {
  298.         printf("%c", operandB[i++]);
  299.     }
  300.     for (; i < result_len; i++) {
  301.         printf("%d", operandB[i]);
  302.     }
  303.     NEWLINE;
  304.  
  305.     free(operandA);
  306.     free(operandB);
  307.  
  308.     free(string);
  309.  
  310.     return 0;
  311. }
  312.  
  313. int main()
  314. {
  315.     int ret;
  316.  
  317.     if ((ret = init())) {
  318.         puts("\n[Usage] [+-]0-9 +,-,* [+-]0-9: <number> <operation> <number>.");
  319.     }
  320.  
  321.     return ret;
  322. }
  323.  
  324.  
  325. /* Find sign; return 1 for '+', -1 for '-' and 0 for not found. */
  326. template <class type>
  327. int find_sign(type term[])
  328. {
  329.     if (term[0] == '-') {
  330.         return -1;
  331.     }
  332.     else if (term[0] == '+') {
  333.         return 1;
  334.     }
  335.  
  336.     // no sign
  337.     return 0;
  338. }
  339.  
  340.  
  341.  
  342. unsigned int arrsub(int termA[], int termB[], unsigned int lenA, unsigned int lenB, unsigned int base)
  343. {
  344.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  345.     int signA = find_sign(termA);
  346.     int signB = find_sign(termB);
  347.  
  348.     // Skip sign OR set sign to 1 if no sign was found.
  349.     unsigned int termA_1st_digit, termB_1st_digit;
  350.     termA_1st_digit = termB_1st_digit = 0;
  351.  
  352.     if (signA) {
  353.         termA_1st_digit++;
  354.     }
  355.     else {
  356.         signA = 1;
  357.     }
  358.  
  359.     if (signB) {
  360.         termB_1st_digit++;
  361.     }
  362.     else {
  363.         signB = 1;
  364.     }
  365.  
  366.     /* Find the order relation between termA and termB. */
  367.     int order = arrnumber_cmp(termA, termB, lenA, lenB);
  368.  
  369.     //    -a - b = - (a + b)                  a - -b = a + b
  370.     if (((signA == -1) && (signB == 1)) || ((signA == 1) && (signB == -1))) {
  371.         if (signA == -1) {
  372.  
  373.             if (termB_1st_digit == 0) {
  374.                 lenB = arrnshift(termB, lenB, termB_1st_digit, 1);
  375.             }
  376.  
  377.             termB[0] = '-';
  378.         }
  379.         else {
  380.             arrnshift(termB, lenB, 0, -1);
  381.             lenB--;
  382.         }
  383.  
  384.         return arradd(termA, termB, lenA, lenB, base);
  385.     }
  386.  
  387.     //    -a - (-b) = -a + b
  388.     else if (signB == -1) {
  389.         signB = 1;
  390.     }
  391.  
  392.     // The remaining calculation: a - b = a + (-b)
  393.     else {
  394.         signB = -1;
  395.     }
  396.  
  397.  
  398.     /* So there's either (-a + b) OR (a + (-b)) to calculate */
  399.  
  400.  
  401.     /*[Obs] The next statemates make sure that the smaller number is the negative number
  402.      * and if any signs are changed, set result_sign accordingly.
  403.      */
  404.     int result_sign = 0;
  405.  
  406.  
  407.     /* Subbing numbers equal in module => 0. */
  408.     if (!order) {
  409.         termB[0] = 0;
  410.         return 1;
  411.     }
  412.  
  413.     /*If a > b AND -a + b to calculate; then flip signs: a + (-b). */
  414.     else if (order > 0 && (signA == -1)) {
  415.         result_sign = signA;  // Set result_sign = sign of the greater number (a > b).
  416.  
  417.         signA = 1;
  418.         signB = -1;
  419.  
  420.     }
  421.     /*Elif a < b AND a + (-b) to calculate; then flip signs: -a + b */
  422.     else if (order < 0 && (signB == -1)) {
  423.         result_sign = signB;  // Set result_sign = sign of the greater number (b > a).
  424.  
  425.         signA = -1;
  426.         signB = 1;
  427.     }
  428.  
  429.     /* If termB (which will store the result) is smaller than termA. */
  430.     if (
  431.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  432.         )
  433.     {
  434.         /* Shift termB, starting at the first digit. */
  435.         lenB = arrnshift<int>(termB, lenB, termB_1st_digit, lenA - lenB);
  436.     }
  437.  
  438.  
  439.     /* Operate */
  440.     int iA, jB;
  441.  
  442.     iA = lenA - 1;
  443.     jB = lenB - 1;
  444.  
  445.     int sum;
  446.     sum = 0;
  447.  
  448.  
  449.     /* Right to left do signed addition. */
  450.     while (
  451.         iA >= (int)termA_1st_digit &&
  452.         jB >= (int)termB_1st_digit
  453.         )
  454.     {
  455.         sum = termA[iA] * signA + termB[jB] * signB;
  456.  
  457.         if (sum < 0) {
  458.             // Borrow from the positive number.
  459.             if (signA == 1) {
  460.                 sum += arrborrow(termA, iA, base);
  461.             }
  462.             else {
  463.                 sum += arrborrow(termB, jB, base);
  464.             }
  465.  
  466.         }
  467.  
  468.         termB[jB] = sum;
  469.  
  470.         iA--; jB--;
  471.     }
  472.    
  473.     /* Count insegnificant zeros. */
  474.     int offset = termB_1st_digit;
  475.    
  476.     while (offset < (int)lenB && !termB[offset]) {
  477.         offset++;
  478.     }
  479.  
  480.     offset -= termB_1st_digit;
  481.  
  482.     /* Delete insegnificant zeros, if any. */
  483.     lenB = arrnshift<int>(termB, lenB, termB_1st_digit, -offset);
  484.    
  485.  
  486.     /* If signs were changed apply result_sign. */
  487.     if (result_sign == -1) {
  488.         if (termB_1st_digit > 0) {
  489.             termB[0] = '-';
  490.         }
  491.         else {
  492.             lenB = arrnfill<int>(termB, lenB, 0, 1, (int)'-');
  493.         }
  494.     }
  495.     else if (termB_1st_digit > 0) { // (Pozitive result) If termB has sign remove it.
  496.         lenB = arrnshift(termB, lenB, 0, -1);
  497.     }
  498.  
  499.  
  500.     return lenB;
  501. }
  502.  
  503.  
  504. int arrborrow(int arr[], unsigned int poz, unsigned int base)
  505. {
  506.     int i, found;
  507.  
  508.     i = poz - 1; // The next position to look for borrow.
  509.     found = 0;   // Whether there is "lender" to borrow from.
  510.  
  511.     /* Find "lender" right to left and borrow, if possible. */
  512.     for (; i >= 0 && !found; i--) {
  513.         if (arr[i] && arr[i] < (int)base) {
  514.  
  515.             arr[i]--;
  516.             found = 1;
  517.         }
  518.     }
  519.  
  520.     /* No "lender". */
  521.     if (!found) {
  522.         return -1;
  523.     }
  524.  
  525.     /* Else lender was found, and borrowed from "it". */
  526.  
  527.     /* Distribute the borrow, left to right. */
  528.     for (i += 2; i < (int)poz; i++) {
  529.         arr[i] += base - 1;
  530.     }
  531.  
  532.     /* The borrower gets full unit. */
  533.     arr[i] += base;
  534.  
  535.     return base;
  536. }
  537.  
  538. unsigned int arradd(int termA[], int termB[], unsigned int lenA, unsigned int lenB, unsigned int base)
  539. {
  540.  
  541.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  542.     int signA = find_sign(termA);
  543.     int signB = find_sign(termB);
  544.  
  545.     // Skip sign OR set sign to 1 if no sign was found.
  546.     unsigned int termA_1st_digit, termB_1st_digit;
  547.     termA_1st_digit = termB_1st_digit = 0;
  548.  
  549.     if (signA) {
  550.         termA_1st_digit++;
  551.     }
  552.     else {
  553.         signA = 1;
  554.     }
  555.  
  556.     if (signB) {
  557.         termB_1st_digit++;
  558.     }
  559.     else {
  560.         signB = 1;
  561.     }
  562.  
  563.  
  564.     /* If signs are different, return call arrsub. */
  565.     if (signA != signB) {
  566.  
  567.         if (signA == -1) {
  568.             /* -a + b = -a - (-b) */
  569.             lenB = arrnfill<int>(termB, lenB, 0, 1, (int)'-');
  570.  
  571.             return arrsub(termA, termB, lenA, lenB, base);
  572.         }
  573.  
  574.         else {
  575.             /* a + (- b) = a - b */
  576.             lenB = arrnshift<int>(termB, lenB, 0, -1);
  577.  
  578.             return arrsub(termA, termB, lenA, lenB, base);
  579.         }
  580.     }
  581.  
  582.     /* If termB (which will store the result) is smaller than termA. */
  583.     if (
  584.         (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
  585.         )
  586.     {
  587.         /* Shift termB, starting at the first digit. */
  588.         lenB = arrnshift<int>(termB, lenB, termB_1st_digit, lenA - lenB);
  589.     }
  590.  
  591.  
  592.     /* Operate */
  593.  
  594.     int iA, jB;
  595.  
  596.     /* Used for iterating. */
  597.     iA = lenA - 1;
  598.     jB = lenB - 1;
  599.  
  600.     int sum, transport;
  601.     sum = transport = 0;
  602.  
  603.  
  604.     /* Right to left add. */
  605.     while (
  606.         iA >= (int)termA_1st_digit &&
  607.         jB >= (int)termB_1st_digit
  608.         )
  609.     {
  610.         sum = termA[iA] + termB[jB] + transport;
  611.  
  612.         termB[jB] = sum % (int)base;
  613.         transport = (sum >= (int)base) ? 1 : 0;           // t = (sum - termB[i]) / base;
  614.  
  615.         iA--; jB--;
  616.     }
  617.  
  618.  
  619.     /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
  620.     while (jB >= (int)termB_1st_digit && transport) {
  621.         sum = termB[jB] + transport;
  622.  
  623.         termB[jB] = sum % (int)base;
  624.         transport = (sum >= (int)base) ? 1 : 0;
  625.  
  626.         jB--;
  627.     }
  628.  
  629.     /* If there's transport: shift by 1, starting at the index of 1st_digit
  630.     * and fill new position with 1 (transport);
  631.     */
  632.     if (transport) {
  633.         arrnfill<int>(termB, lenB, termB_1st_digit, 1, (int)transport);
  634.         lenB++;
  635.     }
  636.  
  637.     return lenB;
  638. }
  639.  
  640.  
  641. unsigned int arrmultiply(int termA[], int termB[], unsigned int lenA, unsigned int lenB, unsigned int base)
  642. {
  643.     /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
  644.     int signA = find_sign(termA);
  645.     int signB = find_sign(termB);
  646.  
  647.     // Skip sign OR set sign to 1 if no sign was found.
  648.     unsigned int termA_1st_digit, termB_1st_digit;
  649.     termA_1st_digit = termB_1st_digit = 0;
  650.  
  651.     if (signA) {
  652.         termA_1st_digit++;
  653.     }
  654.     else {
  655.         signA = 1;
  656.     }
  657.  
  658.     if (signB) {
  659.         termB_1st_digit++;
  660.     }
  661.     else {
  662.         signB = 1;
  663.     }
  664.  
  665.     /* 0 * ... */
  666.     if ((lenA - termA_1st_digit) == 1 && termA[termA_1st_digit] == 0) {
  667.         termB[0] = 0;
  668.         return 1;
  669.     }
  670.    
  671.     /* ... * 0 */
  672.     if ((lenB - termB_1st_digit) == 1 && termB[termB_1st_digit] == 0) {
  673.         termB[0] = 0;
  674.         return 1;
  675.     }
  676.  
  677.     /* Get result sign. */
  678.     int result_sign = signA * signB;
  679.  
  680.  
  681.     /* Allocate memory for multiplicand and multiplier. */
  682.     int *multiplicand, *multiplier;
  683.  
  684.     multiplicand = (int *) ec_malloc((lenA + lenB + 1) * sizeof(int));
  685.  
  686.     multiplier = (int *) ec_malloc(MAX(lenA, lenB) * sizeof(int));
  687.  
  688.     unsigned int lenM, lenm;
  689.  
  690.     /* Copy the "shorter" number into multiplier (for less shifts of the multiplicand). */
  691.     if (lenA > lenB || lenA == lenB) {
  692.         lenM = arrncpy(multiplicand, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit);
  693.         lenm = arrncpy(multiplier, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit);
  694.     }
  695.     else if (lenB > lenA) {
  696.         lenM = arrncpy(multiplicand, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit);
  697.  
  698.         lenm = arrncpy(multiplier, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit);
  699.     }
  700.  
  701.     /* Make the result (termB) 0. */
  702.     unsigned int result_len = lenA + lenB + 1;
  703.  
  704.     for (unsigned int i = 0; i < result_len; i++) {
  705.         termB[i] = 0;
  706.     }
  707.     unsigned int jRes = result_len - 1;
  708.  
  709.  
  710.     for (int i = lenm - 1, sum = 0, transport = 0; i >= 0; i--) {
  711.  
  712.         for (int j = lenM - 1; j >= 0 && jRes >= 0; j--, jRes--) {
  713.  
  714.             /* Multiply and do the sum. */
  715.             sum =  (multiplier[i] * multiplicand[j]) + termB[jRes] + transport;
  716.  
  717.             /* Get the rest. */
  718.             termB[jRes] = (sum % base);
  719.  
  720.             /* Get the transport. */
  721.             transport = (sum - termB[jRes]) / base;
  722.         }
  723.  
  724.         if (transport) {
  725.             termB[jRes] = transport;
  726.             transport = 0;
  727.         }
  728.  
  729.         jRes = result_len - 1;
  730.  
  731.         /* abc -> abc0 -> abc00 -> abc000 -> ...*/
  732.         lenM = arrnshift<int>(multiplicand, lenM, lenM, 1);
  733.     }
  734.  
  735.     /* Count the number of insegnificant zeors. */
  736.     int offset = 0;
  737.     while (offset < (int)result_len && !termB[offset]) {
  738.         offset++;
  739.     }
  740.  
  741.     /* Set sign. */
  742.     if (result_sign == -1) {
  743.         termB[0] = '-';
  744.         termB_1st_digit = 1;
  745.         offset--;
  746.     }
  747.     else {
  748.         termB_1st_digit = 0;
  749.     }
  750.  
  751.     /* Delete insegnificant zeros, if any. */
  752.     lenB = arrnshift<int>(termB, result_len, termB_1st_digit, -offset);
  753.  
  754.  
  755.     free(multiplicand);
  756.     free(multiplier);
  757.  
  758.     return lenB;
  759. }
  760.  
  761.  
  762. /* "Delete" from the startingI, offset elements (including the startingI element). */
  763. template <class type>
  764. unsigned int arrnshrink(type arr[], unsigned int len, unsigned int startingI, int offset)
  765. {
  766.     offset *= -1;
  767.  
  768.     if (offset >= (int)len) {
  769.         return len;
  770.     }
  771.  
  772.     /* Start at the startingIndex. */
  773.     int begin = startingI;
  774.     /* End at the last Index(len-1), minus the offset. */
  775.     int end = len - 1 - offset;
  776.  
  777.     /* Left to right, a[i] = a[i + offset]. */
  778.     for (
  779.         int i = begin;
  780.         i <= end;
  781.         i++)
  782.     {
  783.         arr[i] = arr[i + offset];
  784.     }
  785.  
  786.  
  787.     return len - offset;
  788. }
  789.  
  790.  
  791. /* Shift by enlarging to the left or to the right(if startingI >= len). */
  792. template <class type>
  793. unsigned int arrnfill(type arr[], unsigned int len, unsigned int startingI, int offset, type fill)
  794. {
  795.  
  796.     //arr = (type *)ec_realloc(arr, len * sizeof(type) + offset);
  797.  
  798.     /* Shift after end of arr = fill len -> len + offset =
  799.     * = left shift by enlarging the arr.
  800.     */
  801.     if (startingI >= len) {
  802.         len = len + offset;
  803.  
  804.         for (unsigned int i = len - offset; i < len; i++) {
  805.             arr[i] = fill;
  806.         }
  807.  
  808.         return len;
  809.     }
  810.  
  811.     /* Start at last Index(len-1), plus the offset. */
  812.     int begin = len - 1 + offset;
  813.     /* End at the startingIndex + offset. */
  814.     int end = offset + startingI;
  815.  
  816.     /* Right to left, a[i] = a[i - offset] */
  817.     for (
  818.         int i = begin;
  819.         i >= end;
  820.         i--)
  821.     {
  822.         arr[i] = arr[i - offset];
  823.     }
  824.  
  825.     /* Left to right, from startingIndex until (startingIndex + offset), fill. */
  826.     for (int i = end - offset; i < end; i++) {
  827.         arr[i] = fill;
  828.     }
  829.  
  830.     return len + offset;
  831. }
  832.  
  833.  
  834. /* Shift array (fill = 0) for pozitive offset, shrink for negative offset. */
  835. template <class type>
  836. unsigned int arrnshift(type arr[], unsigned int len, unsigned int startingI, int offset)
  837. {
  838.     if (!offset || !len) {
  839.         return len;
  840.     }
  841.  
  842.     /* Shift by enlarging to the left or to the right(if startingI >= len). */
  843.     if (offset > 0) {
  844.         return arrnfill<type>(arr, len, startingI, offset, (type)0);
  845.     }
  846.  
  847.     /* Shrink */
  848.     return arrnshrink<type>(arr, len, startingI, offset);
  849. }
  850.  
  851.  
  852. /* Compares two arrnumbers (their modoule!). */
  853. template <class type>
  854. int arrnumber_cmp(type termA[], type termB[], unsigned int lenA, unsigned int lenB)
  855. {
  856.     unsigned int iA, jB;
  857.  
  858.     iA = jB = 0;
  859.  
  860.     if (find_sign(termA)) {
  861.         iA++;
  862.     }
  863.  
  864.     if (find_sign(termB)) {
  865.         jB++;
  866.     }
  867.  
  868.     if ((lenA - iA) - (lenB - jB)) {
  869.         return (lenA - iA) - (lenB - jB);
  870.     }
  871.  
  872.     for (; iA < lenA; iA++, jB++) {
  873.         if (termA[iA] != termB[jB]) {
  874.  
  875.             return termA[iA] - termB[jB];
  876.         }
  877.     }
  878.  
  879.     return 0;
  880. }
  881.  
  882.  
  883. /* Copies int arrDest, offset elements from arrStr, begining with the startingI. */
  884. template <class type>
  885. unsigned int arrncpy(type arrDest[], type arrSrc[], unsigned int len, unsigned int startingI, int offset)
  886. {
  887.     if (startingI >= len || len <= 0) {
  888.         return 0;
  889.     }
  890.  
  891.     unsigned int jDest = 0;
  892.  
  893.     int end, begin;
  894.  
  895.     if (offset > 0) {
  896.         begin = startingI;
  897.  
  898.         end = startingI + offset;
  899.  
  900.         if (end > (int)len) {
  901.             return 0;
  902.         }
  903.     }
  904.  
  905.     else {
  906.         begin = startingI + offset;
  907.  
  908.         end = startingI;
  909.  
  910.         if (begin < 0) {
  911.             return 0;
  912.         }
  913.     }
  914.  
  915.     for (int i = begin; i <= end ; i++, jDest++) {
  916.         arrDest[jDest] = arrSrc[i];
  917.     }
  918.  
  919.     return jDest;
  920. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement