Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.65 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define CORRECT_ENDING 0
  6. #define WRONG_INPUT -1
  7. #define INCORRECT_FORMAT -2
  8. #define TRUE 1
  9. #define FALSE 0
  10. #define NOT_FOUND -1
  11.  
  12. typedef char string_t[40];
  13. typedef char accumulator_t[61];
  14.  
  15. typedef struct big_float
  16. {
  17.     string_t mant;
  18.     long int pow;
  19.     char _sgn;
  20. } big_float_t;
  21.  
  22. int standartize_float(big_float_t * num)
  23. {
  24.     if (num->mant[28] >= '5' || (num->mant[29] > '5' && num->mant[28] == '4'))
  25.         num->mant[27]++;
  26.  
  27.     for (int i = strlen(num->mant) - 1; i > 0 ; i--)
  28.         num->mant[i + 1] = num->mant[i];
  29.     for (int i = strlen(num->mant) - 1; i > 0 ; i--)
  30.         num->mant[i + 1] = num->mant[i];
  31.  
  32.     num->mant[1] = '.';
  33.     num->mant[0] = '0';
  34.  
  35.     num->pow += 28;
  36.  
  37.     if (num->pow > 99999 || num->pow < -99999)
  38.         return INCORRECT_FORMAT;
  39.  
  40.     return CORRECT_ENDING;
  41. }
  42.  
  43. void put_header(void)
  44. {
  45.     printf("This program is ment to perform division in long arithmetics.\n\n");
  46.     printf("Enter two numbers in the following way:\n");
  47.     printf(" 1           2                      3   4  \n");
  48.     printf("(+-)-------------------------------(+-)-----\n\n");
  49.     printf("Where:\n1 - sign of mantiss (unnecessary),\n2 - mantiss (<=30 symbols),\n");
  50.     printf("3 - sign of power (unnecessary),\n4 - power (<=5 symbols).\n\n ");
  51. }
  52.  
  53. int cmp(string_t num1, string_t num2)
  54. {
  55.     if (strlen(num1) > strlen(num2)) return 1;
  56.     else if (strlen(num2) > strlen(num1)) return -1;
  57.     else return strcmp(num1, num2);
  58. }
  59.  
  60. void diff_big_float(string_t num1, string_t num2, string_t result)
  61. {
  62.     memset(result, '0', 40);
  63.     result[strlen(num1)] = '\0';
  64.  
  65.     if (strlen(num2) < strlen(num1))
  66.     {
  67.         for(int i = strlen(num2) + 1; i > 0; i--)
  68.             num2[i] = num2[i - 1];
  69.         num2[0] = '0';
  70.     }
  71.  
  72.     for(int i = strlen(num1) - 1; i >= 0; i--)
  73.     {
  74.         result[i] = num1[i] - num2[i] + '0';
  75.         if (result[i] < '0')
  76.         {
  77.             result[i] += 10;
  78.             (num1[i - 1])--;
  79.         }
  80.     }
  81.  
  82.     while (result[0] == '0' && strlen(result) > 1)
  83.     {
  84.         for (int i = 0; i < strlen(result) - 1; i++)
  85.             result[i] = result[i + 1];
  86.         result[strlen(result) - 1] = '\0';
  87.     }
  88.  
  89.     while (num2[0] == '0' && strlen(num2) > 1)
  90.     {
  91.         for (int i = 0; i < strlen(num2) - 1; i++)
  92.             num2[i] = num2[i + 1];
  93.         num2[strlen(num2) - 1] = '\0';
  94.     }
  95. }
  96.  
  97. big_float_t create_big_float(string_t _mant, long int pow, char _sgn)
  98. {
  99.     big_float_t result;
  100.     memset(result.mant, '0', 40);
  101.     strcpy(result.mant, _mant);
  102.     result.pow = pow;
  103.     result._sgn = _sgn;
  104.  
  105.     return result;
  106. }
  107.  
  108. big_float_t divide_big_float(big_float_t dividend, big_float_t divider)
  109. {
  110.     accumulator_t div_acc;
  111.     big_float_t result;
  112.     string_t buf;
  113.     string_t temp;
  114.     char * str_ptr;
  115.     long int power;
  116.     char _sgn;
  117.     int i = 0;
  118.  
  119.     for (int i = 0; i < strlen(divider.mant) + 30; i++)
  120.     {
  121.         if (i < strlen(dividend.mant))
  122.             div_acc[i] = dividend.mant[i];
  123.         else
  124.         {
  125.             div_acc[i] = '0';
  126.             dividend.pow--;
  127.         }
  128.    }
  129.  
  130.    strncpy(buf, div_acc, strlen(divider.mant));
  131.    buf[strlen(divider.mant)] = '\0';
  132.    str_ptr = (div_acc + strlen(divider.mant));
  133.    memset(result.mant, '0', 40);
  134.  
  135.    while(*str_ptr != '\0')
  136.    {
  137.        while (buf[0] == '0')
  138.        {
  139.            for (int j = 0; j < strlen(buf) - 1; j++)
  140.                buf[j] = buf[j + 1];
  141.            buf[strlen(buf) - 1] = '\0';
  142.            strncat(buf, str_ptr, 1);
  143.            if (strcmp(str_ptr, "") == 0)
  144.                break;
  145.            str_ptr++;
  146.            i++;
  147.        }
  148.  
  149.        if (strcmp(str_ptr, "") == 0)
  150.            break;
  151.  
  152.        while (cmp(buf, divider.mant) < 0)
  153.        {
  154.            strncat(buf, str_ptr, 1);
  155.            str_ptr++;
  156.        }
  157.  
  158.        while (cmp(buf, divider.mant) >=0)
  159.        {
  160.            diff_big_float(buf, divider.mant, temp);
  161.            strcpy(buf, temp);
  162.            result.mant[i]++;
  163.        }
  164.        i++;
  165.    }
  166.  
  167.    result.mant[31] = '\0';
  168.    power = dividend.pow - divider.pow;
  169.  
  170.    printf("%s", result.mant);
  171.  
  172.    _sgn = (dividend._sgn == divider._sgn) ? '+' : '-';
  173.    result = create_big_float(result.mant, power, _sgn);
  174.  
  175.    return result;
  176. }
  177.  
  178. void output_big_float(big_float_t result)
  179. {
  180.     printf("Sgn is %c\n", result._sgn);
  181.     printf("Mantiss is %s\n", result.mant);
  182.     printf("Power is %li\n", result.pow);
  183. }
  184.  
  185. void normalize_mant(string_t mant, long int *pow)
  186. {    
  187.  
  188.     if (mant[0] == '+' || mant[0] == '-')
  189.     {
  190.         for (int i = 0; i < strlen(mant) - 1; i++)
  191.             mant[i] = mant[i + 1];
  192.         mant[strlen(mant) - 1] = '\0';
  193.     }
  194.  
  195.    if (strchr(mant, '.'))
  196.    {
  197.        int delta;
  198.        int _dotpos;
  199.  
  200.  
  201.        for (int i = 0; i < strlen(mant); i++)
  202.            if (mant[i] == '.')
  203.            {
  204.                _dotpos = i;
  205.                break;
  206.            }
  207.  
  208.        delta = strlen(mant) - _dotpos - 1;
  209.  
  210.        for (int i = _dotpos; i < strlen(mant) - 1; i++)
  211.            mant[i] = mant[i + 1];
  212.        mant[strlen(mant) - 1] = '\0';
  213.  
  214.        *pow -= delta;
  215.    }
  216.  
  217.    while (mant[0] == '0' && strlen(mant) > 1)
  218.    {
  219.        for (int i = 0; i < strlen(mant) - 1; i++)
  220.            mant[i] = mant[i + 1];
  221.        mant[strlen(mant) - 1] = '\0';
  222.    }
  223. }
  224.  
  225. int process_raw_string(string_t string, big_float_t * res)
  226. {
  227.     char _is_exp;
  228.     char _sgn;
  229.     int dot_cnt = 0;
  230.     long int pow_num = 1;
  231.     int ecnt_ = 0;
  232.     int sgn_cnt = 0;
  233.     int num_cnt = 0;
  234.     string_t power;
  235.     string_t mnts_;
  236.  
  237.     _sgn = (string[0] == '-') ? '-' : '+';
  238.     _is_exp = (strchr(string, 'E')) ? TRUE : FALSE;
  239.  
  240.  
  241.     for (int i = 0; i < strlen(string); i++)
  242.     {
  243.         if (string[i] == 'E') ecnt_++;
  244.  
  245.         else if (string[i] == '.') dot_cnt++;
  246.         else if (string[i] == '+' || string[i] == '-')
  247.         {
  248.             sgn_cnt++;
  249.             if (i != 0 && string[i - 1] != 'E')
  250.                 return INCORRECT_FORMAT;
  251.         }
  252.  
  253.         else if (string[i] < '0' || string[i] > '9')
  254.             return INCORRECT_FORMAT;
  255.     }
  256.  
  257.     if (ecnt_ > 1 || dot_cnt > 1 || sgn_cnt > 2) return INCORRECT_FORMAT;
  258.     if (strpbrk(string, "E.") != NULL && dot_cnt == 1)
  259.         if (*strpbrk(string, "E.") == 'E')
  260.             return INCORRECT_FORMAT;
  261.  
  262.     if (_is_exp)
  263.     {
  264.         strcpy(power, strchr(string, 'E') + 1);
  265.         strtok(string, "E");
  266.         strcpy(mnts_, string);
  267.  
  268.         if (strcmp(power, "0") == 0) pow_num = 0;
  269.         else pow_num = atol(power);
  270.  
  271.         if (pow_num < -99999 || pow_num > 99999)
  272.             return INCORRECT_FORMAT;
  273.     }
  274.  
  275.     else strcpy(mnts_, string);
  276.  
  277.     for (int i = 0; i < strlen(mnts_); i++)
  278.         if (string[i] >= '0' && string[i] <= '9') num_cnt++;
  279.  
  280.     if (!num_cnt) return INCORRECT_FORMAT;
  281.  
  282.     normalize_mant(mnts_, &pow_num);
  283.     (*res) = create_big_float(mnts_, pow_num, _sgn);
  284.  
  285.     return CORRECT_ENDING;
  286. }
  287.  
  288. int main()
  289. {
  290.     string_t string1, string2;
  291.     big_float_t num1, num2, result;
  292.     int rc;
  293.  
  294.     put_header();
  295.  
  296.     printf("Enter first number:\n");
  297.     scanf("%s", string1);
  298.  
  299.     printf("Enter second number:\n");
  300.     scanf("%s", string2);
  301.  
  302.     rc = process_raw_string(string1, &num1);
  303.     if (rc)
  304.     {
  305.         printf("Incorrect data.\n");
  306.         return INCORRECT_FORMAT;
  307.     }
  308.  
  309.     rc = process_raw_string(string2, &num2);
  310.     if (rc)
  311.     {
  312.         printf("Incorrect data.\n");
  313.         return INCORRECT_FORMAT;
  314.     }
  315.  
  316.     result = divide_big_float(num1, num2);
  317.     if (standartize_float(&result) != CORRECT_ENDING)
  318.         return INCORRECT_FORMAT;
  319.  
  320.     output_big_float(result);
  321.     return CORRECT_ENDING;
  322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement