Advertisement
Krudener

Untitled

Sep 29th, 2019
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.45 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. #define ERROR_CODE -1
  6. #define RIGHT 0
  7. #define INPUT_OK 1
  8. #define ALLOWED_INPUT_SIZE 38
  9. #define SIGN_QUANTITY_LIMIT 2
  10. #define DEGREE_LIMIT 1
  11. #define DOT_LIMIT 1
  12. #define POSITIVE_NUMBER 1
  13. #define NEGATIVE_NUMBER -1
  14. #define TRUE 1
  15. #define FALSE 0
  16. #define DIGITS_SIZE 32
  17.  
  18. struct BigDecimal
  19. {
  20.  
  21.     int size;
  22.     int digits[DIGITS_SIZE];
  23.     int E;
  24.     int sign;
  25.  
  26. };
  27.  
  28. /*1)Смоделировать операцию деления действительного числа
  29. на действительное число в форме (+,-)m.n Е (+,-)K, где
  30. суммарная длина мантиссы (m+n) - до 30 значащих цифр, а
  31. величина порядка K - до 5 цифр. Результат выдать в форме
  32.  (+,-)0.m1 Е (+,-)K1, где m1 - до 30 значащих цифр, а K1 - до 5
  33. цифр.
  34.  *
  35.  * */
  36. void welcome_text()
  37. {
  38.     printf("This program performs the operation of dividing real numbers \n"
  39.            "Data entry begins strictly with the sign of the number(+ or -) \n"
  40.            "If there is degree in number, then the sign of degree (+ or"
  41.            " -) is also indicated strictly after E \n"
  42.            "If you enter E, there should be no spaces between numbers and E \n"
  43.            "The number entered must not exceed 30 characters \n"
  44.            "The size of the input degree must not exceed 5 characters \n"
  45.            "Real numbers must be entered through a dot \n"
  46.            "                    1             15             30\n"
  47.            "                    |-------------|--------------|\n");
  48. }
  49.  
  50. void swap(int *xp, int *yp)/*Функция, меняющая местами числа*/
  51. {
  52.     int temp = *xp;
  53.     *xp = *yp;
  54.     *yp = temp;
  55. }
  56.  
  57. void printArrayResult(int *res, int *size, int *E)
  58. {
  59.     printf("0.");
  60.  
  61.     int i = *size - 1;
  62.     while ((res[i] == 0) && (i > 0))
  63.     {
  64.         --(*size);
  65.         E = E - 1;
  66.         i--;
  67.     }
  68.     for (int j = 0; j < *size; j++)
  69.     {
  70.         printf("%d", res[j]);
  71.     }
  72. }
  73.  
  74. void printBigDecimal(struct BigDecimal val)
  75. {
  76.     if (val.sign < 0)
  77.     {
  78.         printf("-");
  79.     }
  80.     else
  81.     {
  82.         printf("+");
  83.     }
  84.     printArrayResult(val.digits, &val.size, &val.E);
  85.  
  86.     val.E = val.E + val.size;
  87.     if (val.E != 0)
  88.     {
  89.         printf("e");
  90.     }
  91.     if (val.E > 0)
  92.     {
  93.         printf("+");
  94.     }
  95.     if (val.E != 0)
  96.     {
  97.         printf("%d", val.E);
  98.     }
  99. }
  100.  
  101. int compare(int *a, int *b, int size)
  102. {
  103.  
  104.     for (int i = 0; i < size; i++)
  105.     {
  106.         if (a[i] > b[i])
  107.         {
  108.             return 1;
  109.         }
  110.         else if (b[i] > a[i])
  111.         {
  112.             return -1;
  113.         }
  114.     }
  115.  
  116.     return 0;
  117. }
  118.  
  119. void minus(int array1[], int array2[], int size, int returnArray[])
  120. {
  121.  
  122.  
  123.     for (int i = size - 1; i >= 0; i--)
  124.     {
  125.  
  126.         if (array1[i] < array2[i])
  127.         {
  128.             array1[i] += 10;
  129.             array1[i - 1] -= 1;
  130.         }
  131.  
  132.         int res = array1[i] - array2[i];
  133.         returnArray[i] = res;
  134.     }
  135. }
  136.  
  137. void incrementResult(int resultArray[], int index)
  138. {
  139.  
  140.     resultArray[index]++;
  141.     if (resultArray[index] >= 10)
  142.     {
  143.         incrementResult(resultArray, index - 1);
  144.         resultArray[index] -= 10;
  145.     }
  146. }
  147.  
  148. void shiftRight(int array[], int size, int shift)
  149. {
  150.  
  151.     for (int i = size - 1; i >= 0; i--)
  152.     {
  153.         int offset = i - shift;
  154.         if (offset < size && offset >= 0)
  155.         {
  156.             array[i] = array[offset];
  157.         }
  158.         else
  159.         {
  160.             array[i] = 0;
  161.         }
  162.     }
  163. }
  164.  
  165. void shiftLeft(int array[], int size, int shift)
  166. {
  167.  
  168.     for (int i = 0; i < size; i++)
  169.     {
  170.         int offset = i + shift;
  171.         if (offset < size && offset >= 0)
  172.         {
  173.             array[i] = array[offset];
  174.         }
  175.         else
  176.         {
  177.             array[i] = 0;
  178.         }
  179.     }
  180. }
  181.  
  182. int divide(int array1[], int array2[], int size, int returnArray[])
  183. {
  184.  
  185.     int shiftsAmount = 0;
  186.     int compareResult = 0;
  187.     do
  188.     {
  189.  
  190.         compareResult = compare(array1, array2, size);
  191.  
  192.         if (compareResult < 0)
  193.         {
  194.             shiftRight(array2, size, 1);
  195.             shiftLeft(returnArray, size, 1);
  196.             shiftsAmount++;
  197.             continue;
  198.         }
  199.  
  200.         if (returnArray[0] != 0)
  201.         {
  202.             return shiftsAmount * -1;
  203.         }
  204.  
  205.         incrementResult(returnArray, size - 1);
  206.         minus(array1, array2, size, array1);
  207.  
  208.     }
  209.     while (compareResult != 0);
  210.  
  211.     return shiftsAmount * -1;
  212. }
  213.  
  214. struct BigDecimal normalize(struct BigDecimal decimal)
  215. {
  216.  
  217.     struct BigDecimal res = {.sign = decimal.sign, .size = DIGITS_SIZE};
  218.  
  219.     int e = decimal.E;
  220.  
  221.     for (int i = 0; i < res.size; i++)
  222.     {
  223.         if (i < decimal.size)
  224.         {
  225.             res.digits[i] = decimal.digits[i];
  226.         }
  227.         else
  228.         {
  229.             res.digits[i] = 0;
  230.             e--;
  231.         }
  232.     }
  233.     res.E = e;
  234.  
  235.     return res;
  236. }
  237.  
  238. struct BigDecimal denormalize(struct BigDecimal decimal)
  239. {
  240.  
  241.     int leftZero = 0;
  242.     int rightZero = 0;
  243.  
  244.     for (int i = 0; i < decimal.size; i++)
  245.     {
  246.         if (decimal.digits[i] == 0)
  247.         {
  248.             leftZero++;
  249.         }
  250.         else
  251.         {
  252.             break;
  253.         }
  254.     }
  255.  
  256.     for (int i = decimal.size - 1; i >= 0; i--)
  257.     {
  258.         if (decimal.digits[i] == 0)
  259.         {
  260.             rightZero++;
  261.         }
  262.         else
  263.         {
  264.             break;
  265.         }
  266.     }
  267.  
  268.     struct BigDecimal res = {
  269.             .size = decimal.size - (leftZero + rightZero),
  270.             .sign = decimal.sign,
  271.             .E = decimal.E + rightZero
  272.     };
  273.  
  274.     for (int j = leftZero; j < decimal.size - rightZero; ++j)
  275.     {
  276.         res.digits[j - leftZero] = decimal.digits[j];
  277.     }
  278.  
  279.  
  280.     int finalSize = 30;
  281.  
  282.     if (res.size > finalSize)
  283.     {
  284.         if (res.digits[finalSize] >= 5)
  285.         {
  286.             incrementResult(res.digits, finalSize - 1);
  287.         }
  288.         int eSign = res.E / abs(res.E);
  289.         if (eSign > 0)
  290.         {
  291.             res.E--;
  292.         }
  293.         else
  294.         {
  295.             res.E++;
  296.         }
  297.     }
  298.  
  299.  
  300.     res.size = finalSize;
  301.  
  302.     return res;
  303. }
  304.  
  305.  
  306. struct BigDecimal floatingDivide(struct BigDecimal val1, struct BigDecimal val2)
  307. {
  308.     struct BigDecimal result = {
  309.             .sign = val1.sign * val2.sign,/*Знак результата*/
  310.             /*Размер чуть больше 30 для округления по 31-ой цифре*/
  311.             .size = DIGITS_SIZE,
  312.             /*Зануление всех цифр числа для избежания мусора в ячейках*/
  313.             .digits = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  314.                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  315.                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  316.     };
  317.  
  318.     struct BigDecimal normVal1 = normalize(val1);
  319.     struct BigDecimal normVal2 = normalize(val2);
  320.  
  321.     int e = 0;
  322.     e = divide(normVal1.digits, normVal2.digits, DIGITS_SIZE, result.digits);
  323.     result.E = normVal1.E - normVal2.E + e;
  324.     struct BigDecimal denormResult = denormalize(result);
  325.  
  326.     return denormResult;
  327. }
  328.  
  329. /*Функция, убирающая нули сразу после точки*/
  330. void remove_zero(int *digits, int *size, int *E)
  331. {
  332.     int i = 0;
  333.     int size_remember = *size;
  334.     /*Если встретился 0 в начале массива цифр, то смещаем его в конец*/
  335.     /*С последующем уменьшением размера массива цифр*/
  336.     while (digits[i] == 0)
  337.     {
  338.         for (int j = 0; j < (size_remember - 1); j++)
  339.         {
  340.             swap(&digits[j], &digits[j + 1]);
  341.         }
  342.         --*size;
  343.     }
  344. }
  345.  
  346. void number_split(char *string, int *digits, int *size, int *E, int *sign)
  347. {
  348.     /*Переменная для исключения добавления лишнего нуля в массив цифр*/
  349.     int useless_zero = FALSE;
  350.     if (string[1] == '0' && (string[0] == '-' || string[0] == '+') && (string[2] == '.'))
  351.     {
  352.         useless_zero = TRUE;
  353.     }
  354.     /*Переменная для отрезания незначащих нулей в конце*/
  355.     /*для исключения их добавления в массив цифр*/
  356.     int size_to_delete = 0;
  357.     int index = 0;
  358.     /*Проверка знака перед числом*/
  359.     if (string[0] == '-')
  360.     {
  361.         *sign = NEGATIVE_NUMBER;
  362.     }
  363.     else
  364.     {
  365.         *sign = POSITIVE_NUMBER;
  366.     }
  367.     int E_flag = FALSE;/*Переменная для проверки наличия Е в числе*/
  368.     int sign_E = POSITIVE_NUMBER;/*Знак порядка*/
  369.     /*Переменная запоминающая старый порядок перед нормализацией*/
  370.     int old_E = 0;
  371.     int point_flag = FALSE;/*Переменная для проверки наличия точки в числе*/
  372.     /*Проверка наличия целой части*/
  373.     while (index < strlen(string))
  374.     {
  375.         /*Встретилась ли точка при записи числа*/
  376.         if (string[index] == '.')
  377.         {
  378.             point_flag = TRUE;
  379.         }
  380.         /*Встретилась ли E при записи числа*/
  381.         if (string[index] == 'E')
  382.         {
  383.             if (string[index + 1] == '-')
  384.             {
  385.                 sign_E = NEGATIVE_NUMBER;
  386.             }
  387.             E_flag = TRUE;
  388.             int index_zero_check = index;
  389.             /*Удаление незначащих нулей с конца*/
  390.             while (string[index_zero_check - 1] == '0')
  391.             {
  392.                 index_zero_check--;
  393.                 ++(*E);
  394.                 size_to_delete++;
  395.             }
  396.         }
  397.         /*Проверка на наличие целой части числа*/
  398.         if ((string[index] != '+') && (string[index] != '-') && (string[index] != '.') &&
  399.             (string[index] != 'E') && (E_flag == FALSE))
  400.         {
  401.             /*Встретилась ли точка?Т.к. целой части нет, то порядок далее убывает*/
  402.             if (point_flag == TRUE)
  403.             {
  404.                 --(*E);
  405.             }
  406.             /*Перевод чисел из char в int*/
  407.             digits[*size] = string[index] - '0';
  408.             ++(*size);
  409.         }
  410.         /*Запись изначального порядка числа*/
  411.         if (E_flag == TRUE)
  412.         {
  413.             if ((string[index] != 'E') && (string[index] != '+') && (string[index] != '-'))
  414.             {
  415.                 /*Запись старого порядка числа*/
  416.                 old_E = old_E + (string[index] - '0');
  417.                 if (strlen(string) > index + 1)
  418.                 {
  419.                     old_E = old_E * 10;
  420.                 }
  421.             }
  422.         }
  423.         index++;
  424.     }
  425.     /*Корректировка размера массива цифр в соотв с наличием незначащих нулей*/
  426.     *size = *size - size_to_delete;
  427.     /*Смещение цифр в зависимости от наличия незначащего нуля в начале*/
  428.     if (useless_zero == TRUE)
  429.     {
  430.         for (int j = 0; j < (*size - 1); j++)
  431.         {
  432.             swap(&digits[j], &digits[j + 1]);
  433.         }
  434.         --(*size);
  435.     }
  436.     /*Преобразование порядка с учетом знака Е*/
  437.     old_E *= sign_E;
  438.     /*Получение финального порядка числа*/
  439.     *E = *E + old_E;
  440.     remove_zero(digits, size, E);
  441. }
  442.  
  443. char input_format_check(char *string)
  444. {
  445.     /*Массив допустимых символов*/
  446.     char allowed_array[14] = "0123456789E+-.";
  447.     int size = 0;
  448.     int E_quantity_check = 0; /*Подсчет кол-ва встречаемого символа E*/
  449.     int sign_quantity_check = 0;/*Подсчет кол-ва встречаемого символа знака*/
  450.     int dot_quantity_check = 0;/*Подсчет кол-ва встречаемого символа точки*/
  451.     /*Если число не начинается со знака,то ошибка*/
  452.     if ((string[size] != '-') && (string[size] != '+'))
  453.     {
  454.         return ERROR_CODE;
  455.     }
  456.     /*Движение по строке до ее конца*/
  457.     while (size != strlen(string))
  458.     {
  459.         /*Переменная для проверки корректности введенного сивола*/
  460.         int check_correct_input = 0;
  461.         for (int i = 0; i < 14; i++)
  462.         {
  463.             /*Входит ли введенный символ в список допустиых*/
  464.             if (string[size] == allowed_array[i])
  465.             {
  466.                 check_correct_input = 1;
  467.             }
  468.         }
  469.         if (string[size] == 'E')
  470.         {
  471.             /*Проверка обязательного знака после E*/
  472.             if ((string[size + 1] != '-') && (string[size + 1] != '+'))
  473.             {
  474.                 /*Проверка введен ли порядок после E*/
  475.                 if ((string[size + 2] != '0') && (string[size + 2] != '1')
  476.                     && (string[size + 2] != '2') && (string[size + 2] != '3')
  477.                     && (string[size + 2] != '4') && (string[size + 2] != '5')
  478.                     && (string[size + 2] != '6') && (string[size + 2] != '7')
  479.                     && (string[size + 2] != '8') && (string[size + 2] != '9'))
  480.                 {
  481.                     return ERROR_CODE;
  482.                 }
  483.             }
  484.             E_quantity_check++;
  485.         }
  486.         if (string[size] == '-' || string[size] == '+')
  487.         {
  488.             /*Проверка знака на первой позиции*/
  489.             if ((size != 0))
  490.             {
  491.                 /*Проверка знака после E*/
  492.                 if (string[size - 1] != 'E')
  493.                 {
  494.                     return ERROR_CODE;
  495.                 }
  496.             }
  497.             if (string[size + 1] == 'E')
  498.             {
  499.                 return ERROR_CODE;
  500.             }
  501.             sign_quantity_check++;
  502.         }
  503.         if (string[size] == '.')
  504.         {
  505.             /*Исключение чисел с запятой в порядке*/
  506.             if (E_quantity_check == DEGREE_LIMIT)
  507.             {
  508.                 return ERROR_CODE;
  509.             }
  510.             dot_quantity_check++;
  511.         }
  512.         /*Проверка допустимого количества элементов*/
  513.         if ((check_correct_input != 1) || (sign_quantity_check > SIGN_QUANTITY_LIMIT) \
  514.  || (E_quantity_check > DEGREE_LIMIT) || (dot_quantity_check > DOT_LIMIT))
  515.         {
  516.             return ERROR_CODE;
  517.         }
  518.         /*Переход к следующему символу строки*/
  519.         size++;
  520.     }
  521.     return RIGHT;
  522. }
  523.  
  524. int input_function(char *input)
  525. {
  526.     if (scanf("%100s", input) != INPUT_OK)
  527.     {
  528.         return ERROR_CODE;
  529.     }
  530.     /*Проверка длинны введенного чилса*/
  531.     if (strlen(input) > ALLOWED_INPUT_SIZE)
  532.     {
  533.         printf("Input size exceeded");
  534.         return ERROR_CODE;
  535.     }
  536.     /*Проверка корректности введенного формата числа*/
  537.     if (input_format_check(input) != RIGHT)
  538.     {
  539.         printf("Invalid input format");
  540.         return ERROR_CODE;
  541.     }
  542.     return RIGHT;
  543. }
  544.  
  545. int main()
  546. {
  547.     /*Правила ввода текста в консоли*/
  548.     welcome_text();
  549.     char input[ALLOWED_INPUT_SIZE];/*Строка ввода первого числа*/
  550.     char input2[ALLOWED_INPUT_SIZE];/*Строка второго  числа*/
  551.     printf("Input first number:");
  552.     /*Проверка правильного формата первого числа*/
  553.     if (input_function(input) == ERROR_CODE)
  554.     {
  555.         return ERROR_CODE;
  556.     }
  557.     printf("\n");
  558.     printf("                     1             15             30\n"
  559.            "                     |-------------|--------------|\n");
  560.     printf("Input second number:");
  561.     /*Проверка правильного формата второго числа*/
  562.     if (input_function(input2) == ERROR_CODE)
  563.     {
  564.         return ERROR_CODE;
  565.     }
  566.     /* Переменные для нормализации вида числа*/
  567.     int digits[ALLOWED_INPUT_SIZE]; /* Массив цифр первого числа */
  568.     int sign = 1;/*Знак первого числа*/
  569.     int size = 0;/*Размер массива цифр первого числа*/
  570.     int E = 0; /*Порядок первого числа*/
  571.     int digits2[ALLOWED_INPUT_SIZE];/* Массив цифр второго числа */
  572.     int sign2 = 1;/*Знак второго числа*/
  573.     int size2 = 0;/*Размер массива цифр второго числа*/
  574.     int E2 = 0;/*Порядок второго числа*/
  575.  
  576.     number_split(input, digits, &size, &E, &sign);/*Нормализация первого числа*/
  577.  
  578.     number_split(input2, digits2, &size2, &E2, &sign2);/*Нормализация второго числа*/
  579.  
  580.  
  581.  
  582.     struct BigDecimal number1;/*Cтруктура первого числа*/
  583.     struct BigDecimal number2;/*Структура второго числа*/
  584.     number1.sign = sign;/*Добавление в структуру знака числа*/
  585.     number1.E = E;/*Добавление в структуру порядка числа*/
  586.     number1.size = size;/*Добавление в структуру размера числа*/
  587.     /*Добавление в структуру массива цифр числа*/
  588.     for (int i = 0; i < size; i++)
  589.     {
  590.         number1.digits[i] = digits[i];
  591.     }
  592.     number2.sign = sign2;/*Добавление в структуру знака числа*/
  593.     number2.E = E2;/*Добавление в структуру порядка числа*/
  594.     number2.size = size2;/*Добавление в структуру размера числа*/
  595.     /*Добавление в структуру массива цифр числа*/
  596.     for (int i = 0; i < size2; i++)
  597.     {
  598.         number2.digits[i] = digits2[i];
  599.     }
  600.     /*Создание структуры для результата*/
  601.     struct BigDecimal result = floatingDivide(number1, number2);
  602.     /*Вывод результата*/
  603.     printBigDecimal(result);
  604.     return RIGHT;
  605. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement