Advertisement
Krudener

Untitled

Sep 22nd, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.49 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.  
  17. /*1)Смоделировать операцию деления действительного числа
  18. на действительное число в форме (+,-)m.n Е (+,-)K, где
  19. суммарная длина мантиссы (m+n) - до 30 значащих цифр, а
  20. величина порядка K - до 5 цифр. Результат выдать в форме
  21.  (+,-)0.m1 Е (+,-)K1, где m1 - до 30 значащих цифр, а K1 - до 5
  22. цифр.
  23.  *
  24.  * */
  25.  
  26. typedef struct // структура для хранения чисел в проавильном формате
  27. {
  28.     int size; // размер числа
  29.     int digits[ALLOWED_INPUT_SIZE]; // Число
  30.     int E; // порядок числа (значение после Е)
  31.     int sign;
  32. } big_decimal;
  33.  
  34. void welcome_text()
  35. {
  36.     printf("Data entry begins strictly with the sign of the number(+ or -) \n"
  37.            "If there is degree in number, then the sign of degree (+ or"
  38.            " -) is also indicated strictly after E \n"
  39.            "If you enter E, there should be no spaces between numbers and E \n"
  40.            "The number entered must not exceed 30 characters \n"
  41.            "The size of the input degree must not exceed 5 characters \n"
  42.            "Real numbers must be entered through a dot \n"
  43.            "                    ------------------------------\n");
  44. }
  45.  
  46. void swap(int *xp, int *yp)/*Функция, меняющая местами числа*/
  47. {
  48.     int temp = *xp;
  49.     *xp = *yp;
  50.     *yp = temp;
  51. }
  52.  
  53. /*Функция, убирающая нули сразу после точки*/
  54. void remove_zero(int *digits, int *size, int *E)
  55. {
  56.  
  57.     int i = 0;
  58.     int size_remember = *size;
  59.  
  60.     /*Если встретился 0 в начале массива цифр, то смещаем его в конец*/
  61.     /*С последующем уменьшением размера массива цифр*/
  62.     while (digits[i] == 0)
  63.     {
  64.         for (int j = 0; j < (size_remember - 1); j++)
  65.         {
  66.             swap(&digits[j], &digits[j + 1]);
  67.         }
  68.         --*size;
  69.     }
  70.  
  71. }
  72.  
  73. void printArrayResult(int *res, int size)
  74. {
  75.     for (int j = 0; j < size; j++)
  76.     {
  77.         printf("Element[%d] = %d\n", j, res[j]);
  78.     }
  79. }
  80.  
  81. void printNumber(int num)
  82. {
  83.     printf("Number = %d\n", num);
  84. }
  85.  
  86. int compare(int *a, int *b, int arraySize, int index)
  87. {
  88.  
  89.     int val1 = a[index];
  90.     int val2 = b[index];
  91.  
  92.     if (index == arraySize)
  93.     {
  94.         return 1;
  95.     }
  96.  
  97.     if (val1 == val2)
  98.     {
  99.         return compare(a, b, arraySize, index + 1);
  100.     }
  101.  
  102.     if (val1 > val2)
  103.     {
  104.         return 1;
  105.     }
  106.     else
  107.     {
  108.         return -1;
  109.     }
  110. }
  111.  
  112. void minus(int *array1, int *array2, int size, int *returnArray)
  113. {
  114.  
  115.     int borrow = -1;
  116.  
  117.     for (int i = size - 1; i >= 0; i--)
  118.     {
  119.  
  120.         if (array1[i] < array2[i])
  121.         {
  122.             borrow = i - 1;
  123.             array1[i] += 10;
  124.         }
  125.  
  126.         int res = array1[i] - array2[i];
  127.         if (borrow == i)
  128.         {
  129.             borrow = -1;
  130.             res--;
  131.         }
  132.         returnArray[i] = res;
  133.     }
  134. }
  135.  
  136. void incrementResult(int resultArray[], int index)
  137. {
  138.  
  139.     resultArray[index]++;
  140.     if (resultArray[index] >= 10)
  141.     {
  142.         incrementResult(resultArray, index - 1);
  143.         resultArray[index] -= 10;
  144.     }
  145. }
  146.  
  147. void divide(int *array1, int *array2, int size, int *returnArray)
  148. {
  149.  
  150.     int compareResult = 0;
  151.     do
  152.     {
  153.  
  154.         incrementResult(returnArray, size - 1);
  155.  
  156.         minus(array1, array2, size, array1);
  157.         printArrayResult(array1, size);
  158.         compareResult = compare(array1, array2, size, 0);
  159.         printNumber(compareResult);
  160.  
  161.     }
  162.     while (compareResult > 0);
  163. }
  164.  
  165. void number_split(char *string, int *digits, int *size, int *E, int *sign)
  166. {
  167.  
  168.     /*Переменная для исключения добавления лишнего нуля в массив цифр*/
  169.     int useless_zero = FALSE;
  170.     if (string[1] == '0' && (string[0] == '-' || string[0] == '+') && (string[2] == '.'))
  171.     {
  172.         useless_zero = TRUE;
  173.     }
  174.  
  175.     /*Переменная для отрезания незначащих нулей в конце*/
  176.     /*для исключения их добавления в массив цифр*/
  177.     int size_to_delete = 0;
  178.     int index = 0;
  179.  
  180.     /*Проверка знака перед числом*/
  181.     if (string[0] == '-')
  182.     {
  183.         *sign = NEGATIVE_NUMBER;
  184.     }
  185.     else
  186.     {
  187.         *sign = POSITIVE_NUMBER;
  188.     }
  189.  
  190.     int E_flag = FALSE;/*Переменная для проверки наличия Е в числе*/
  191.     int sign_E = POSITIVE_NUMBER;/*Знак порядка*/
  192.     /*Переменная запоминающая старый порядок перед нормализацией*/
  193.     int old_E = 0;
  194.     int point_flag = FALSE;/*Переменная для проверки наличия точки в числе*/
  195.  
  196.     /*Проверка наличия целой части*/
  197.     while (index < strlen(string))
  198.     {
  199.         /*Встретилась ли точка при записи числа*/
  200.         if (string[index] == '.')
  201.         {
  202.             point_flag = TRUE;
  203.         }
  204.  
  205.         /*Встретилась ли E при записи числа*/
  206.         if (string[index] == 'E')
  207.         {
  208.             if (string[index + 1] == '-')
  209.             {
  210.                 sign_E = NEGATIVE_NUMBER;
  211.             }
  212.  
  213.             E_flag = TRUE;
  214.             int index_zero_check = index;
  215.  
  216.             /*Удаление незначащих нулей с конца*/
  217.             while (string[index_zero_check - 1] == '0')
  218.             {
  219.                 index_zero_check--;
  220.                 ++(*E);
  221.                 size_to_delete++;
  222.             }
  223.         }
  224.  
  225.         /*Проверка на наличие целой части числа*/
  226.         if ((string[index] != '+') && (string[index] != '-') && (string[index] != '.') &&
  227.             (string[index] != 'E') && (E_flag == FALSE))
  228.         {
  229.             /*Встретилась ли точка?Т.к. целой части нет, то порядок далее убывает*/
  230.             if (point_flag == TRUE)
  231.             {
  232.                 --(*E);
  233.             }
  234.             /*Перевод чисел из char в int*/
  235.             digits[*size] = string[index] - '0';
  236.             ++(*size);
  237.         }
  238.  
  239.         /*Запись изначального порядка числа*/
  240.         if (E_flag == TRUE)
  241.         {
  242.             if ((string[index] != 'E') && (string[index] != '+') && (string[index] != '-'))
  243.             {
  244.                 /*Запись старого порядка числа*/
  245.                 old_E = old_E + (string[index] - '0');
  246.                 if (strlen(string) > index + 1)
  247.                 {
  248.                     old_E = old_E * 10;
  249.                 }
  250.             }
  251.         }
  252.  
  253.         index++;
  254.  
  255.     }
  256.  
  257.     /*Корректировка размера массива цифр в соотв с наличием незначащих нулей*/
  258.     *size = *size - size_to_delete;
  259.  
  260.     /*Смещение цифр в зависимости от наличия незначащего нуля в начале*/
  261.     if (useless_zero == TRUE)
  262.     {
  263.         for (int j = 0; j < (*size - 1); j++)
  264.         {
  265.             swap(&digits[j], &digits[j + 1]);
  266.         }
  267.         --(*size);
  268.     }
  269.  
  270.     /*Преобразование порядка с учетом знака Е*/
  271.     old_E *= sign_E;
  272.     /*Получение финального порядка числа*/
  273.     *E = *E + old_E;
  274.     remove_zero(digits, size, E);
  275.  
  276. }
  277.  
  278.  
  279. char input_format_check(char *string)
  280. {
  281.  
  282.     /*Массив допустимых символов*/
  283.     char allowed_array[14] = "0123456789E+-.";
  284.     int size = 0;
  285.     int E_quantity_check = 0; /*Подсчет кол-ва встречаемого символа E*/
  286.     int sign_quantity_check = 0;/*Подсчет кол-ва встречаемого символа знака*/
  287.     int dot_quantity_check = 0;/*Подсчет кол-ва встречаемого символа точки*/
  288.  
  289.     /*Если число не начинается со знака,то ошибка*/
  290.     if ((string[size] != '-') && (string[size] != '+'))
  291.     {
  292.         return ERROR_CODE;
  293.     }
  294.  
  295.     /*Движение по строке до ее конца*/
  296.     while (size != strlen(string))
  297.     {
  298.         /*Переменная для проверки корректности введенного сивола*/
  299.         int check_correct_input = 0;
  300.  
  301.         for (int i = 0; i < 14; i++)
  302.         {
  303.             /*Входит ли введенный символ в список допустиых*/
  304.             if (string[size] == allowed_array[i])
  305.             {
  306.                 check_correct_input = 1;
  307.             }
  308.         }
  309.  
  310.         if (string[size] == 'E')
  311.         {
  312.             /*Проверка обязательного знака после E*/
  313.             if ((string[size + 1] != '-') && (string[size + 1] != '+'))
  314.             {
  315.  
  316.                 /*Проверка введен ли порядок после E*/
  317.                 if ((string[size + 2] != '0') && (string[size + 2] != '1')
  318.                     && (string[size + 2] != '2') && (string[size + 2] != '3')
  319.                     && (string[size + 2] != '4') && (string[size + 2] != '5')
  320.                     && (string[size + 2] != '6') && (string[size + 2] != '7')
  321.                     && (string[size + 2] != '8') && (string[size + 2] != '9'))
  322.                 {
  323.                     return ERROR_CODE;
  324.                 }
  325.  
  326.             }
  327.  
  328.             E_quantity_check++;
  329.  
  330.         }
  331.         if (string[size] == '-' || string[size] == '+')
  332.         {
  333.  
  334.             /*Проверка знака на первой позиции*/
  335.             if ((size != 0))
  336.             {
  337.  
  338.                 /*Проверка знака после E*/
  339.                 if (string[size - 1] != 'E')
  340.                 {
  341.                     return ERROR_CODE;
  342.                 }
  343.  
  344.             }
  345.  
  346.             if (string[size + 1] == 'E')
  347.             {
  348.                 return ERROR_CODE;
  349.             }
  350.  
  351.             sign_quantity_check++;
  352.  
  353.         }
  354.  
  355.         if (string[size] == '.')
  356.         {
  357.  
  358.             /*Исключение чисел с запятой в порядке*/
  359.             if (E_quantity_check == DEGREE_LIMIT)
  360.             {
  361.                 return ERROR_CODE;
  362.             }
  363.  
  364.             dot_quantity_check++;
  365.  
  366.         }
  367.  
  368.         /*Проверка допустимого количества элементов*/
  369.         if ((check_correct_input != 1) || (sign_quantity_check > SIGN_QUANTITY_LIMIT) \
  370.  || (E_quantity_check > DEGREE_LIMIT) || (dot_quantity_check > DOT_LIMIT))
  371.         {
  372.             return ERROR_CODE;
  373.         }
  374.  
  375.         /*Переход к следующему символу строки*/
  376.         size++;
  377.  
  378.     }
  379.  
  380.     return RIGHT;
  381.  
  382. }
  383.  
  384.  
  385. int input_function(char *input)
  386. {
  387.  
  388.     if (scanf("%100s", input) != INPUT_OK)
  389.     {
  390.         return ERROR_CODE;
  391.     }
  392.  
  393.     /*Проверка длинны введенного чилса*/
  394.     if (strlen(input) > ALLOWED_INPUT_SIZE)
  395.     {
  396.         printf("Input size exceeded");
  397.         return ERROR_CODE;
  398.     }
  399.  
  400.     /*Проверка корректности введенного формата числа*/
  401.     if (input_format_check(input) != RIGHT)
  402.     {
  403.         printf("Invalid input format");
  404.         return ERROR_CODE;
  405.     }
  406.  
  407.     return RIGHT;
  408.  
  409. }
  410.  
  411.  
  412. int main()
  413. {
  414.  
  415.     welcome_text();/*Правила ввода текста в консоли*/
  416.  
  417.     char input[ALLOWED_INPUT_SIZE];/*Строка ввода первого числа*/
  418.     char input2[ALLOWED_INPUT_SIZE];/*Строка второго  числа*/
  419.     printf("Input first number:");
  420.  
  421.     /*Проверка правильного формата первого числа*/
  422.     if (input_function(input) == ERROR_CODE)
  423.     {
  424.         return ERROR_CODE;
  425.     }
  426.  
  427.     printf("                     ------------------------------\n");
  428.     printf("Input second number:");
  429.  
  430.     /*Проверка правильного формата второго числа*/
  431.     if (input_function(input2) == ERROR_CODE)
  432.     {
  433.         return ERROR_CODE;
  434.     }
  435.  
  436.     /* Переменные для нормализации вида числа*/
  437.     int digits[ALLOWED_INPUT_SIZE]; /* Массив цифр первого числа */
  438.     int sign = 1;/*Знак первого числа*/
  439.     int size = 0;/*Размер массива цифр первого числа*/
  440.     int E = 0; /*Порядок первого числа*/
  441.  
  442.     int digits2[ALLOWED_INPUT_SIZE];/* Массив цифр второго числа */
  443.     int sign2 = 1;/*Знак второго числа*/
  444.     int size2 = 0;/*Размер массива цифр второго числа*/
  445.     int E2 = 0;/*Порядок второго числа*/
  446.  
  447.     number_split(input, digits, &size, &E, &sign);/*Нормализация первого числа*/
  448.  
  449.     for (int i = 0; i < size; i++)
  450.     {
  451.         printf("%d ", digits[i]);
  452.     }
  453.     printf("sign = %d, E = %d , size = %d \n", sign, E, size);
  454.  
  455.     number_split(input2, digits2, &size2, &E2, &sign2);/*Нормализация второго числа*/
  456.  
  457.     for (int i = 0; i < size2; i++)
  458.     {
  459.         printf("%d ", digits2[i]);
  460.     }
  461.     printf("sign = %d, E = %d , size = %d \n", sign2, E2, size2);
  462.  
  463.     /*Сборка всех данных в структуру*/
  464.     big_decimal number_1;
  465.     big_decimal number_2;
  466.  
  467.     number_1.sign = sign;
  468.     number_1.E = E;
  469.     number_1.size = size;
  470.     for (int i = 0; i < number_1.size; i++)
  471.     {
  472.         number_1.digits[i] = digits[i];
  473.     }
  474.  
  475.     number_2.sign = sign2;
  476.     number_2.E = E2;
  477.     number_2.size = size2;
  478.     for (int i = 0; i < number_2.size; i++)
  479.     {
  480.         number_2.digits[i] = digits2[i];
  481.     }
  482.  
  483.     int divRes[number_1.size];
  484.     for (int i = 0; i < number_1.size;i++)
  485.     {
  486.         divRes[i] = 0;
  487.     }
  488.     divide(number_1.digits, number_2.digits, number_1.size, divRes);
  489.     printArrayResult(divRes, number_1.size);
  490.  
  491.     return RIGHT;
  492. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement