Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ctype.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdint.h>
- typedef struct FixedNumber {
- int64_t integer;
- uint32_t fractional;
- } FixedNumber;
- enum RepresentFixedNumber {
- MAX_INTEGER_CNT = 10,
- MAX_FRACTIONAL_CNT = 8,
- };
- const uint32_t SHIFT8 = 1e8;
- const uint64_t SHIFT10 = 1e10;
- bool is_rounded_up(int digits, bool is_tail_zero) {
- return (is_tail_zero && digits % 10 == 5 && (digits / 10) % 2) ||
- digits % 10 > 5 || (!is_tail_zero && digits % 10 == 5);
- }
- bool getnum(FixedNumber* result, bool* is_overflow) {
- char sym;
- int sign = 0;
- result->integer = 0, result->fractional = 0;
- *is_overflow = false;
- int cnt_digits = 0;
- while ((sym = getchar()) != EOF) {
- if (isdigit(sym) || sym == '+' || sym == '-') {
- break;
- }
- }
- if (sym == EOF) {
- return false;
- }
- while (sym != EOF) {
- if (!isdigit(sym) && sym != '+' && sym != '-') {
- break;
- }
- if (sym == '-') {
- sign = 1;
- } else if (isdigit(sym)) {
- if (cnt_digits == MAX_INTEGER_CNT) {
- *is_overflow = true;
- } else {
- result->integer = 10 * result->integer + (sym - '0');
- ++cnt_digits;
- }
- }
- sym = getchar();
- }
- if (sym != '.') {
- result->integer *= sign == 0 ? 1 : -1;
- return true;
- }
- cnt_digits = 0;
- bool is_tail_zero = true;
- while ((sym = getchar()) != EOF) {
- if (!isdigit(sym)) {
- break;
- }
- if (cnt_digits == MAX_FRACTIONAL_CNT + 1) {
- if (sym != '0') {
- is_tail_zero = false;
- }
- continue;
- }
- result->fractional = 10 * result->fractional + (sym - '0');
- ++cnt_digits;
- }
- if (cnt_digits == MAX_FRACTIONAL_CNT + 1 &&
- is_rounded_up(result->fractional % 100, is_tail_zero)) {
- result->fractional = result->fractional / 10 + 1;
- if (result->fractional >= SHIFT8) {
- result->fractional -= SHIFT8;
- ++result->integer;
- if (result->integer >= SHIFT10) {
- *is_overflow = true;
- return true;
- }
- }
- } else if (cnt_digits == MAX_FRACTIONAL_CNT + 1) {
- result->fractional /= 10;
- }
- while (result->fractional != 0 && cnt_digits < MAX_FRACTIONAL_CNT) {
- result->fractional *= 10;
- ++cnt_digits;
- }
- result->integer *= sign == 0 ? 1 : -1;
- return true;
- }
- void print(FixedNumber num) {
- if (num.integer == 0 && num.fractional == 0) {
- printf("0.00000000\n");
- } else {
- printf("%ld.%08u\n", num.integer, num.fractional);
- }
- }
- int main() {
- FixedNumber first, second, result;
- bool is_overflow_1, is_overflow_2;
- while (getnum(&first, &is_overflow_1) && getnum(&second, &is_overflow_2)) {
- if (is_overflow_1 || is_overflow_2 || (second.fractional == 0 && second.integer == 0)) {
- printf("ERROR\n");
- continue;
- }
- __int128_t divided = first.integer;
- divided = divided * SHIFT8 + first.fractional;
- divided *= SHIFT8 * 10; // extra 10 to identify first deleted digit (<5 =5 >5)
- __int128_t diviser = second.integer;
- diviser = diviser * SHIFT8 + second.fractional;
- __int128_t quotient = divided / diviser;
- int sign_of_result = 0;
- if (quotient < 0) {
- sign_of_result = 1;
- quotient *= -1;
- }
- if (is_rounded_up(quotient % 100, divided % diviser)) {
- quotient = quotient / 10 + 1;
- } else {
- quotient /= 10;
- }
- result.fractional = quotient % SHIFT8;
- quotient /= SHIFT8;
- if (quotient >= SHIFT10) {
- printf("ERROR\n");
- continue;
- }
- result.integer = quotient * (sign_of_result == 0 ? 1 : -1);
- print(result);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement