Advertisement
Guest User

Untitled

a guest
Nov 25th, 2017
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 14.80 KB | None | 0 0
  1. /*
  2.  *
  3.  * Numlib library for dealing with integers greater than 32 bits.
  4.  * This functions provided by this library are not as effective as default
  5.  * operators (e.g. +, -, *, /), but allows calculations on integers larger
  6.  * than 32 bits (i.e. > 2 147 483 647 (2^31 - 1))
  7.  *
  8.  */
  9.  
  10. #if defined _numlib_included
  11.     #endinput
  12. #endif
  13. #define _numlib_included
  14.  
  15. #define NUMBER_MAX_LENGTH 256 //The maximum length of the numbers
  16. #define NUMBER_MAX_FACTORIAL 20 //The maximum factorial count
  17.  
  18. #define ushort%0; new %0[6]; //Usage: ushort var;
  19. #define uint%0; new %0[11]; //Usage: uint var;
  20. #define ulong%0; new %0[21]; //Usage: ulong var;
  21. #define uocta%0; new %0[40]; //Usage: uocta var;
  22.  
  23. /* Natives (for tricking Pawno)
  24.  
  25. native add(integer1[], integer2[]);
  26. native subtract(integer1[], integer2[]);
  27. native multiply(integer1[], integer2[]);
  28. native num_power(integer[], power);
  29. native divide(dividend[], divisor);
  30. native get_remainder(dividend[], divisor);
  31. native is_greater(integer1[], integer2[]);
  32. native is_less(integer1[], integer2[]);
  33. native is_num(num[]);
  34. native set_num(integer[], val[]);
  35. native factorial(integer[]);
  36. */
  37.  
  38. /*
  39.     add:
  40.         Add two integers
  41.  
  42.     Parameters:
  43.         number1[]   An integer represented as an array
  44.         number2[]   An integer represented as an array
  45.  
  46.     Returns:
  47.         The sum of number1 and number2 as an array
  48. */
  49.  
  50. stock add(n1[], n2[])
  51. {
  52.     new temp, sum[NUMBER_MAX_LENGTH];
  53.  
  54.     // Support for negative integers
  55.     if(n1[0] == '-' && n2[0] != '-')
  56.     {
  57.         n1[0] = '0';
  58.  
  59.         set_num(sum, subtract(n2, n1));
  60.         return sum;
  61.     }
  62.  
  63.     if(n1[0] != '-' && n2[0] == '-')
  64.     {
  65.         n2[0] = '0';
  66.  
  67.         set_num(sum, subtract(n1, n2));
  68.         return sum;
  69.     }
  70.  
  71.     if(n1[0] == '-' && n2[0] == '-')
  72.     {
  73.         n1[0] = '0';
  74.         n2[0] = '0';
  75.     }
  76.  
  77.     new number1[NUMBER_MAX_LENGTH],
  78.         number2[NUMBER_MAX_LENGTH];
  79.  
  80.     set_num(number1, n1);
  81.     set_num(number2, n2);
  82.  
  83.     // Make both number strings contain as many characters (i.e. zero padding)
  84.     new len1 = strlen(number1), len2 = strlen(number2);
  85.     if(len1 > len2)
  86.     {
  87.         for(new i = 0; i < len1-len2; i ++)
  88.         {
  89.             strins(number2, "0", 0, NUMBER_MAX_LENGTH);
  90.         }
  91.     }
  92.     else if(len1 < len2)
  93.     {
  94.         for(new i = 0; i < len2-len1; i ++)
  95.         {
  96.             strins(number1, "0", 0, NUMBER_MAX_LENGTH);
  97.         }
  98.     }
  99.  
  100.     // Loop through numbers one by one, starting from the end
  101.     for(new i = strlen(number1)-1; i >= 0; i--)
  102.     {
  103.         // Get the number to a string, then convert to an integer
  104.         new int1_str[2], int2_str[2], int1, int2, temp_sum;
  105.         strmid(int1_str, number1, i, i+1, sizeof(int1_str));
  106.         strmid(int2_str, number2, i, i+1, sizeof(int2_str));
  107.  
  108.         int1 = strval(int1_str);
  109.         int2 = strval(int2_str);
  110.  
  111.         // Sum the numbers, add the possible number from 'hold'
  112.         temp_sum = int1 + int2 + temp;
  113.  
  114.         // Check if the sum is greater than 9, if it is, subtract 10 and add 1 to 'hold'
  115.         if(temp_sum > 9)
  116.         {
  117.             temp = 1;
  118.             temp_sum -= 10;
  119.         }
  120.         else
  121.         {
  122.             temp = 0;
  123.         }
  124.  
  125.         // Convert the sum calculated in the loop to a string
  126.         new temp_sum_str[3];
  127.         format(temp_sum_str, sizeof(temp_sum_str), "%d", temp_sum);
  128.  
  129.         // Add the sum calculated in the loop to the total sum
  130.         strins(sum, temp_sum_str, 0, sizeof(sum));
  131.     }
  132.  
  133.     // Check for any number on 'hold'
  134.     if(temp != 0)
  135.     {
  136.         // Add the number from 'hold' if any
  137.         format(sum, sizeof(sum), "%d%s", temp, sum);
  138.     }
  139.  
  140.     // Remove insignificant zeroes
  141.     for(new i = 0; i < strlen(sum); i++)
  142.     {
  143.         if(sum[i] != 48 || i == strlen(sum)-1)
  144.         {
  145.             strdel(sum, 0, i);
  146.             break;
  147.         }
  148.     }
  149.  
  150.     return sum;
  151. }
  152.  
  153. /*
  154.     subtract:
  155.         Subtract two integers
  156.  
  157.     Parameters:
  158.         number1[]   An integer represented as an array
  159.         number2[]   An integer represented as an array
  160.  
  161.     Returns:
  162.         The remainder of number1 and number2 as an array
  163. */
  164.  
  165. stock subtract(n1[], n2[])
  166. {
  167.     new temp, remainder[NUMBER_MAX_LENGTH];
  168.  
  169.     // Support for negative integers
  170.     if(n1[0] == '-' && n2[0] != '-')
  171.     {
  172.         n1[0] = '0';
  173.  
  174.         format(remainder, NUMBER_MAX_LENGTH, "-%s", add(n1, n2));
  175.         return remainder;
  176.     }
  177.  
  178.     if(n1[0] != '-' && n2[0] == '-')
  179.     {
  180.         n2[0] = '0';
  181.  
  182.         set_num(remainder, add(n1, n2));
  183.         return remainder;
  184.     }
  185.  
  186.     if(n1[0] == '-' && n2[0] == '-')
  187.     {
  188.         n2[0] = '0';
  189.     }
  190.  
  191.     new number1[NUMBER_MAX_LENGTH],
  192.         number2[NUMBER_MAX_LENGTH];
  193.  
  194.     set_num(number1, n1);
  195.     set_num(number2, n2);
  196.  
  197.     // Make both number strings contain as many characters (i.e. zero padding)
  198.     new len1 = strlen(number1), len2 = strlen(number2);
  199.     if(len1 > len2)
  200.     {
  201.         for(new i = 0; i < len1-len2; i ++)
  202.         {
  203.             strins(number2, "0", 0, NUMBER_MAX_LENGTH);
  204.         }
  205.     }
  206.     else if(len1 < len2)
  207.     {
  208.         for(new i = 0; i < len2-len1; i ++)
  209.         {
  210.             strins(number1, "0", 0, NUMBER_MAX_LENGTH);
  211.         }
  212.     }
  213.  
  214.     for(new i = strlen(number1)-1; i >= 0; i--)
  215.     {
  216.         // Get the number to a string, then convert to an integer
  217.         new int1_str[2], int2_str[2], int1, int2, temp_remainder;
  218.         strmid(int1_str, number1, i, i+1, sizeof(int1_str));
  219.         strmid(int2_str, number2, i, i+1, sizeof(int2_str));
  220.  
  221.         int1 = strval(int1_str);
  222.         int2 = strval(int2_str);
  223.  
  224.         // Subtract the numbers, subtract the possible number from 'hold'
  225.         temp_remainder = int1 - int2 - temp;
  226.  
  227.         // Check if the remainder is less than 0, if it is, add 10 to the remainder and add 1 to 'hold'
  228.         if(temp_remainder < 0)
  229.         {
  230.             temp = 1;
  231.             temp_remainder += 10;
  232.         }
  233.         else
  234.         {
  235.             temp = 0;
  236.         }
  237.  
  238.         // Convert the remainder calculated in the loop to a string
  239.         new temp_remainder_str[3];
  240.         format(temp_remainder_str, sizeof(temp_remainder_str), "%d", temp_remainder);
  241.  
  242.         // Add the remainder calculated in the loop to the total remainder
  243.         strins(remainder, temp_remainder_str, 0, sizeof(remainder));
  244.     }
  245.  
  246.     // Check if something is in 'hold'
  247.     if(temp != 0)
  248.     {
  249.         // Calculate the smallest multiple of 10 higher than our result (remainder)
  250.         new len = strlen(remainder);
  251.  
  252.         new from[NUMBER_MAX_LENGTH];
  253.         format(from, sizeof(from), "1");
  254.  
  255.         while(len > 0)
  256.         {
  257.             strcat(from, "0", NUMBER_MAX_LENGTH);
  258.             len --;
  259.         }
  260.  
  261.         // Subtract our remainder from the smallest multiple of 10 higher than the remainder
  262.         // This isn't a sophisticated solution, but works.
  263.         format(remainder, sizeof(remainder), "%s", subtract(from, remainder));
  264.  
  265.         // Remove insignificant zeroes
  266.         for(new i = 0; i < strlen(remainder); i++)
  267.         {
  268.             if(remainder[i] != 48 || i == strlen(remainder)-1)
  269.             {
  270.                 strdel(remainder, 0, i);
  271.                 break;
  272.             }
  273.         }
  274.  
  275.         // Add minus sign
  276.         strins(remainder, "-", 0, NUMBER_MAX_LENGTH);
  277.     }
  278.     else
  279.     {
  280.         // Remove insignificant zeroes
  281.         for(new i = 0; i < strlen(remainder); i++)
  282.         {
  283.             if(remainder[i] != 48 || i == strlen(remainder)-1)
  284.             {
  285.                 strdel(remainder, 0, i);
  286.                 break;
  287.             }
  288.         }
  289.     }
  290.  
  291.     return remainder;
  292. }
  293.  
  294. /*
  295.     is_greater:
  296.         Compares two numbers, determines whether the first one is greater than the second or not
  297.  
  298.     Parameters:
  299.         number1[]   An integer represented as an array
  300.         number2[]   An integer represented as an array
  301.  
  302.     Returns:
  303.         boolean: true or false
  304. */
  305.  
  306. stock is_greater(number1[], number2[])
  307. {
  308.     // Number1 is negative and number2 is positive
  309.     if(number1[0] == 45 && number2[0] != 45) return false;
  310.  
  311.     // Vice versa
  312.     if(number1[0] != 45 && number2[0] == 45) return true;
  313.  
  314.     // The sign of both number is the same, we could try the lengths of the numbers now
  315.  
  316.     // Get rid of preceding zeroes
  317.     for(new i, l = strlen(number1); i != l; i++)
  318.     {
  319.         if(number1[i] == '0')
  320.             strdel(number1, 0, i);
  321.         else break;
  322.     }
  323.  
  324.     for(new i, l = strlen(number2); i != l; i++)
  325.     {
  326.         if(number1[i] == '0')
  327.             strdel(number1, 0, i);
  328.         else break;
  329.     }
  330.  
  331.     new len1, len2;
  332.     len1 = strlen(number1);
  333.     len2 = strlen(number2);
  334.  
  335.     if(len1 > len2) return true;
  336.     if(len1 < len2) return false;
  337.  
  338.     // Reaching this point means that the numbers have the same sign and the same length
  339.     // Now we have to start comparing the numbers digit by digit
  340.  
  341.     for(new i = 0; i < len1; i++)
  342.     {
  343.         // Get the number to a string, then convert to an integer
  344.         new int1_str[2], int2_str[2], int1, int2;
  345.         strmid(int1_str, number1, i, i+1, sizeof(int1_str));
  346.         strmid(int2_str, number2, i, i+1, sizeof(int2_str));
  347.  
  348.         int1 = strval(int1_str);
  349.         int2 = strval(int2_str);
  350.  
  351.         if(int1 > int2) return true;
  352.         if(int1 < int2) return false;
  353.     }
  354.  
  355.     // If we can reach all the way here, the numbers are equal
  356.     return false;
  357. }
  358.  
  359. /*
  360.     is_less:
  361.         Compares two numbers, determines whether the first one is smaller than the second or not
  362.  
  363.     Parameters:
  364.         number1[]   An integer represented as an array
  365.         number2[]   An integer represented as an array
  366.  
  367.     Returns:
  368.         boolean: true or false
  369. */
  370.  
  371. stock is_less(number1[], number2[])
  372. {
  373.     // Number1 is negative and number2 is positive
  374.     if(number1[0] == 45 && number2[0] != 45) return true;
  375.  
  376.     // Vice versa
  377.     if(number1[0] != 45 && number2[0] == 45) return false;
  378.  
  379.     // The sign of both number is the same, we could try the lengths of the numbers now
  380.  
  381.     // Get rid of preceding zeroes
  382.     for(new i, l = strlen(number1); i != l; i++)
  383.     {
  384.         if(number1[i] == '0')
  385.             strdel(number1, 0, i);
  386.         else break;
  387.     }
  388.  
  389.     for(new i, l = strlen(number2); i != l; i++)
  390.     {
  391.         if(number1[i] == '0')
  392.             strdel(number1, 0, i);
  393.         else break;
  394.     }
  395.  
  396.     new len1, len2;
  397.     len1 = strlen(number1);
  398.     len2 = strlen(number2);
  399.  
  400.     if(len1 > len2) return false;
  401.     if(len1 < len2) return true;
  402.  
  403.     // Reaching this point means that the numbers have the same sign and the same length
  404.     // Now we have to start comparing the numbers digit by digit
  405.  
  406.     for(new i = 0; i < len1; i++)
  407.     {
  408.         // Get the number to a string, then convert to an integer
  409.         new int1_str[2], int2_str[2], int1, int2;
  410.         strmid(int1_str, number1, i, i+1, sizeof(int1_str));
  411.         strmid(int2_str, number2, i, i+1, sizeof(int2_str));
  412.  
  413.         int1 = strval(int1_str);
  414.         int2 = strval(int2_str);
  415.  
  416.         if(int1 > int2) return false;
  417.         if(int1 < int2) return true;
  418.     }
  419.  
  420.     // If we can reach all the way here, the numbers are equal
  421.     return false;
  422. }
  423.  
  424. /*
  425.     multiply:
  426.         Multiplies two numbers (represented as char arrays) and returns the result in the form of a char array
  427.  
  428.     Parameters:
  429.         number1[]   An integer represented as an array
  430.         number2[]   An integer represented as an array
  431.  
  432.     Returns:
  433.         The result of the multiplication as a char array (string)
  434. */
  435.  
  436. stock multiply(_number1[], _number2[])
  437. {
  438.     new finalval[NUMBER_MAX_LENGTH], c[NUMBER_MAX_LENGTH], temp[NUMBER_MAX_LENGTH], number1[NUMBER_MAX_LENGTH], number2[NUMBER_MAX_LENGTH], lengtha, lengthb, j, k, x, y, r, sum;
  439.  
  440.     lengtha = strlen(_number1)-1;
  441.     lengthb = strlen(_number2)-1;
  442.  
  443.     strmid(number1, _number1, 0, NUMBER_MAX_LENGTH);
  444.     strmid(number2, _number2, 0, NUMBER_MAX_LENGTH);
  445.  
  446.     for(new i = 0; i <= lengtha; i ++)
  447.     {
  448.             number1[i] = number1[i] - 48;
  449.     }
  450.  
  451.     for(new i = 0; i <= lengthb; i ++)
  452.     {
  453.             number2[i] = number2[i] - 48;
  454.     }
  455.  
  456.     for(new i = lengthb; i >= 0; i --)
  457.     {
  458.         r = 0;
  459.         for(j = lengtha; j >= 0; j --)
  460.         {
  461.             temp[k++] = (number2[i] * number1[j] + r) % 10;
  462.             r = (number2[i] * number1[j] + r) / 10;
  463.         }
  464.         temp[k++] = r;
  465.         x++;
  466.         for(y = 0;y<x;y++)
  467.         {
  468.             temp[k++] = 0;
  469.         }
  470.     }
  471.  
  472.     k = r = 0;
  473.     for(new i = 0; i < lengtha + lengthb + 2; i ++)
  474.     {
  475.          sum = y = 0;
  476.          for(j = 1; j <= lengthb+1; j ++)
  477.          {
  478.              if(i <= lengtha + j)
  479.              {
  480.                  sum = sum + temp[y + i];
  481.              }
  482.              y += j + lengtha + 1;
  483.          }
  484.          c[k++] = (sum + r) % 10;
  485.          r = (sum + r) / 10;
  486.     }
  487.  
  488.     c[k] = r;
  489.     j = 0;
  490.     for(new i = k - 1; i >= 0; i --)
  491.     {
  492.          finalval[j++] = c[i] + 48;
  493.     }
  494.     finalval[j] = '\0';
  495.  
  496.     // Remove insignificant zeroes
  497.     for(new i = 0; i < strlen(finalval); i++)
  498.     {
  499.         if(finalval[i] != 48)
  500.         {
  501.             strdel(finalval, 0, i);
  502.             break;
  503.         }
  504.     }
  505.  
  506.     return finalval;
  507. }
  508.  
  509. /*
  510.     num_power:
  511.         Returns the integer (represented as a string) to the power of x (represented as an integer)
  512.  
  513.     Parameters:
  514.         integer[]   An integer represented as a string
  515.         power   A 32-bit integer
  516.  
  517.     Returns:
  518.         X (represented as a string) raised to the power of  Y (represented as an integer) as a char array (string)
  519. */
  520.  
  521. stock num_power(integer[], power)
  522. {
  523.     new finalstr[NUMBER_MAX_LENGTH];
  524.  
  525.     if(!power)
  526.     {
  527.         strmid(finalstr, "1", 0, NUMBER_MAX_LENGTH);
  528.         return finalstr;
  529.     }
  530.  
  531.     strmid(finalstr, multiply(integer,"1"), 0, NUMBER_MAX_LENGTH);
  532.  
  533.     for(new i=0;i<power-1;i++) strmid(finalstr, multiply(integer,finalstr), 0, NUMBER_MAX_LENGTH);
  534.     return finalstr;
  535. }
  536.  
  537.  
  538. stock divide(const dividend[], divisor){
  539.     new q[NUMBER_MAX_LENGTH];
  540.     new temp=0;
  541.     new j=0;
  542.     for(new i=0;i<strlen(dividend);++i)
  543.     {
  544.          temp = temp*10 + (dividend[i] -48);
  545.          if(temp<divisor) q[j++] = 48;
  546.          else{
  547.              q[j++] = (temp / divisor) + 48;
  548.              temp = temp % divisor;
  549.          }
  550.     }
  551.     q[j] = '\0';
  552.     for(new i = 0;i<strlen(q);++i)
  553.     {
  554.         if(q[i] != 48)
  555.         {
  556.             strdel(q, 0, i);
  557.             break;
  558.         }
  559.     }
  560.     return q;
  561. }
  562.  
  563. /*
  564.     get_remainder:
  565.         Returns the remainder of the division of two numbers (the dividend represented as a string, the divisor represented as a 32-bit integer)
  566.  
  567.     Parameters:
  568.         dividend[]  An integer represented as a string
  569.         divisor A 32-bit integer
  570.  
  571.     Returns:
  572.         The remainder of the division as a 32-bit integer
  573. */
  574.  
  575. stock get_remainder(const dividend[], divisor){
  576.     new temp;
  577.     for(new i=0;i<strlen(dividend);++i)
  578.     {
  579.          temp = temp*10 + (dividend[i] -48);
  580.          if(temp>=divisor) temp = temp % divisor;
  581.     }
  582.     return temp;
  583. }
  584.  
  585. /*
  586.     is_num:
  587.         Checks whether a char array (string) is an actual integer
  588.  
  589.     Parameters:
  590.         num[]   A char array (string)
  591.  
  592.     Returns:
  593.         1 if the string is an integer, 0 if it isn't
  594. */
  595.  
  596.  
  597. stock is_num(num[])
  598. {
  599.     for(new i=0;i<strlen(num);++i) {
  600.         if(num[i] < 48 || num[i] > 57) return false;
  601.     }
  602.     return true;
  603. }
  604.  
  605. /*
  606.     set_num:
  607.         Sets the value of an integer
  608.  
  609.     Parameters:
  610.         integer[]   The integer, represented as a string, whose value should be set
  611.         val[]   The value represented as a string
  612.  
  613.     Returns:
  614.         The characters written
  615. */
  616.  
  617. stock set_num(integer[], const val[]) { format(integer, strlen(val)+1, "%s", val); return strlen(val); }
  618.  
  619. /*
  620.     factorial:
  621.         Get the factorial of an integer
  622.  
  623.     Parameters:
  624.         number1[]   An integer represented as a string
  625.  
  626.     Returns:
  627.         The factorial of the specified integer as an array
  628. */
  629.  
  630. stock factorial(integer[])
  631. {
  632.     new sum[NUMBER_MAX_LENGTH], integer1[NUMBER_MAX_LENGTH];
  633.     format(sum, NUMBER_MAX_LENGTH, "%s", integer);
  634.     format(integer1, NUMBER_MAX_LENGTH, "%s", integer);
  635.     for(new i=0;i<NUMBER_MAX_FACTORIAL;i++)
  636.     {
  637.         if(is_greater(integer1, "1"))
  638.         {
  639.             set_num(sum, multiply(sum, subtract(integer1,"1")));
  640.             set_num(integer1, subtract(integer1,"1"));
  641.         }
  642.         else break;
  643.     }
  644.     return sum;
  645. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement