Advertisement
Krudener

Untitled

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