Advertisement
Ksenia_C

Untitled

Feb 3rd, 2022
1,223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.01 KB | None | 0 0
  1. #include <ctype.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5.  
  6. typedef struct FixedNumber {
  7.     int64_t integer;
  8.     uint32_t fractional;
  9. } FixedNumber;
  10.  
  11. enum RepresentFixedNumber {
  12.     MAX_INTEGER_CNT = 10,
  13.     MAX_FRACTIONAL_CNT = 8,
  14. };
  15. const uint32_t SHIFT8 = 1e8;
  16. const uint64_t SHIFT10 = 1e10;
  17.  
  18. bool is_rounded_up(int digits, bool is_tail_zero) {
  19.     return (is_tail_zero && digits % 10 == 5 && (digits / 10) % 2) ||
  20.         digits % 10 > 5 || (!is_tail_zero && digits % 10 == 5);
  21. }
  22.  
  23.  
  24. bool getnum(FixedNumber* result, bool* is_overflow) {
  25.     char sym;
  26.     int sign = 0;
  27.     result->integer = 0, result->fractional = 0;
  28.     *is_overflow = false;
  29.     int cnt_digits = 0;
  30.     while ((sym = getchar()) != EOF) {
  31.         if (isdigit(sym) || sym == '+' || sym == '-') {
  32.             break;
  33.         }
  34.     }
  35.     if (sym == EOF) {
  36.         return false;
  37.     }
  38.     while (sym != EOF) {
  39.         if (!isdigit(sym) && sym != '+' && sym != '-') {
  40.             break;
  41.         }
  42.         if (sym == '-') {
  43.             sign = 1;
  44.         } else if (isdigit(sym)) {
  45.             if (cnt_digits == MAX_INTEGER_CNT) {
  46.                 *is_overflow = true;
  47.             } else {
  48.                 result->integer = 10 * result->integer + (sym - '0');
  49.                 ++cnt_digits;
  50.             }
  51.         }
  52.         sym = getchar();
  53.     }
  54.     if (sym != '.') {
  55.         result->integer *= sign == 0 ? 1 : -1;
  56.         return true;
  57.     }
  58.     cnt_digits = 0;
  59.     bool is_tail_zero = true;
  60.     while ((sym = getchar()) != EOF) {
  61.         if (!isdigit(sym)) {
  62.             break;
  63.         }
  64.         if (cnt_digits == MAX_FRACTIONAL_CNT + 1) {
  65.             if (sym != '0') {
  66.                 is_tail_zero = false;
  67.             }
  68.             continue;
  69.         }
  70.         result->fractional = 10 * result->fractional + (sym - '0');
  71.         ++cnt_digits;
  72.     }
  73.     if (cnt_digits == MAX_FRACTIONAL_CNT + 1 &&
  74.         is_rounded_up(result->fractional % 100, is_tail_zero)) {
  75.         result->fractional = result->fractional / 10 + 1;
  76.         if (result->fractional >= SHIFT8) {
  77.             result->fractional -= SHIFT8;
  78.             ++result->integer;
  79.             if (result->integer >= SHIFT10) {
  80.                 *is_overflow = true;
  81.                 return true;
  82.             }
  83.         }
  84.     } else if (cnt_digits == MAX_FRACTIONAL_CNT + 1) {
  85.         result->fractional /= 10;
  86.     }
  87.     while (result->fractional != 0 && cnt_digits < MAX_FRACTIONAL_CNT) {
  88.         result->fractional *= 10;
  89.         ++cnt_digits;
  90.     }
  91.     result->integer *= sign == 0 ? 1 : -1;
  92.     return true;
  93. }
  94.  
  95. void print(FixedNumber num) {
  96.     if (num.integer == 0 && num.fractional == 0) {
  97.         printf("0.00000000\n");
  98.     } else {
  99.         printf("%ld.%08u\n", num.integer, num.fractional);
  100.     }
  101. }
  102.  
  103. int main() {
  104.     FixedNumber first, second, result;
  105.     bool is_overflow_1, is_overflow_2;
  106.     while (getnum(&first, &is_overflow_1) && getnum(&second, &is_overflow_2)) {
  107.         if (is_overflow_1 || is_overflow_2 || (second.fractional == 0 && second.integer == 0)) {
  108.             printf("ERROR\n");
  109.             continue;
  110.         }
  111.         __int128_t divided = first.integer;
  112.         divided = divided * SHIFT8 + first.fractional;
  113.         divided *= SHIFT8 * 10;  // extra 10 to identify first deleted digit (<5 =5 >5)
  114.         __int128_t diviser = second.integer;
  115.         diviser = diviser * SHIFT8 + second.fractional;
  116.         __int128_t quotient = divided / diviser;
  117.         int sign_of_result = 0;
  118.         if (quotient < 0) {
  119.             sign_of_result = 1;
  120.             quotient *= -1;
  121.         }
  122.         if (is_rounded_up(quotient % 100, divided % diviser)) {
  123.             quotient = quotient / 10 + 1;
  124.         } else {
  125.             quotient /= 10;
  126.         }
  127.         result.fractional = quotient % SHIFT8;
  128.         quotient /= SHIFT8;
  129.         if (quotient >= SHIFT10) {
  130.             printf("ERROR\n");
  131.             continue;
  132.         }
  133.         result.integer = quotient * (sign_of_result == 0 ? 1 : -1);
  134.         print(result);
  135.     }
  136. }
  137.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement