bool test_big_int_add_2 (Test *test) { BigInt *a, *b, *to; int i; TITLE (); CATCH (!(a = big_int_create (0))); CATCH (!(b = big_int_create (0))); CATCH (!(to = big_int_create (0))); a->memory[0] = 5U; b->memory[0] = 5U; for (i = 1; i < 32; i++) { a->memory[i] = 0U; b->memory[i] = 0U; } a->digits = 32; b->digits = 32; CATCH (!big_int_add (a, b, to)); CATCH (to->digits != 33); CATCH (to->memory[0] != 1U); for (i = 1; i < 33; i++) { CATCH (to->memory[i] != 0U); } big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_add_function_call_2 (Test *test) { BigInt *a, *b, *to; int i; TITLE (); CATCH (!(a = big_int_create (0))); CATCH (!(b = big_int_create (0))); CATCH (!(to = big_int_create (0))); CATCH (!(a->memory = memory_grow (a->memory, 33))); CATCH (!(b->memory = memory_grow (b->memory, 33))); a->memory[0] = 1U; b->memory[0] = 1U; for (i = 1; i < 33; i++) { a->memory[i] = 0U; b->memory[i] = 0U; } a->digits = 33; b->digits = 33; memory_commit_limit (memory_commit_size ()); CATCH (big_int_add (a, b, to)); CATCH (error_at (0).error != ErrorFunctionCall); CATCH (error_at (0).code != 2); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_copy_invalid_operation (Test *test) { BigInt *a, *to; TITLE (); CATCH (!(a = big_int_create (0))); CATCH (!(to = big_int_create (0))); a->digits = 100; CATCH (big_int_copy (a, to)); CATCH (error_at (0).error != ErrorInvalidOperation); big_int_destroy (a); big_int_destroy (to); PASS (); }
bool test_big_int_mul_2 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (123451234512345))); CATCH (!(b = big_int_create (123451234512345))); CATCH (!(to = big_int_create (0))); CATCH (!big_int_mul (a, b, to)); CATCH (!big_int_equals_string (to, "15240207302622001229957399025")); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_mul_1 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (12))); CATCH (!(b = big_int_create (34))); CATCH (!(to = big_int_create (0))); CATCH (!big_int_mul (a, b, to)); CATCH (!big_int_equals_string (to, "408")); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_set (Test *test) { BigInt *integer; char *max = "18446744073709551615"; size_t max_length; size_t i; TITLE (); CATCH (!(integer = big_int_create (0))); CATCH (integer->digits != 1); CATCH (integer->memory[0] != (unsigned char)0); CATCH (!big_int_set (integer, (uint64_t)-1)); max_length = string_length (max); CATCH (integer->digits != max_length); for (i = 0; i < max_length; i++) { CATCH (integer->memory[i] != max[i] - '0'); } CATCH (!big_int_set (integer, 123)); CATCH (integer->digits != 3); CATCH (integer->memory[0] != 1); CATCH (integer->memory[1] != 2); CATCH (integer->memory[2] != 3); big_int_destroy (integer); PASS (); }
int main(void) { int result = 0; printf("BIG_INT calculator version %s\n", CALC_VERSION); printf("Created by valyala ([email protected]) http://valyala.narod.ru\n"); printf("Size of word is %zu bits\n", BIG_INT_WORD_BITS_CNT); printf("BIB_INT library version: %s, build_date: %s\n", big_int_version(), big_int_build_date()); printf("type \\h or \\? for help\n"); if (history_init()) { /* error when initializing history[] array */ result = 1; goto done; } /* init the [module] */ module = big_int_create(1); if (module == NULL) { printf("cannot create [module]\n"); result = 2; goto done; } /* start parsing */ parse(); done: /* free allocated memory */ big_int_destroy(module); history_destroy(); return result; }
bool test_big_int_mul_function_call_1 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (2))); CATCH (!(b = big_int_create (3))); CATCH (!(to = big_int_create (0))); memory_commit_limit (memory_commit_size ()); CATCH (big_int_mul (a, b, to)); CATCH (error_at (0).error != ErrorFunctionCall); CATCH (error_at (0).code != 1); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_add_1 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (123))); CATCH (!(b = big_int_create (456))); CATCH (!(to = big_int_create (0))); CATCH (!big_int_add (a, b, to)); CATCH (to->digits != 3); CATCH (to->memory[0] != 5U); CATCH (to->memory[1] != 7U); CATCH (to->memory[2] != 9U); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_copy_function_call (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (123451234512345))); CATCH (!(b = big_int_create (123451234512345))); CATCH (!(to = big_int_create (0))); CATCH (!big_int_mul (a, b, to)); CATCH (!big_int_mul (a, to, b)); memory_commit_limit (memory_commit_size ()); CATCH (big_int_copy (b, a)); CATCH (error_at (0).error != ErrorFunctionCall); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_add_4 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (999))); CATCH (!(b = big_int_create (11))); CATCH (!(to = big_int_create (0))); CATCH (!big_int_add (a, b, to)); CATCH (to->digits != 4); CATCH (to->memory[0] != 1U); CATCH (to->memory[1] != 0U); CATCH (to->memory[2] != 1U); CATCH (to->memory[3] != 0U); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
bool test_big_int_create_function_call_1 (Test *test) { TITLE (); memory_commit_limit (sizeof (size_t) + sizeof (BigInt) - 1); CATCH (big_int_create (0)); CATCH (error_count () == 0); CATCH (error_at (0).error != ErrorFunctionCall); CATCH (error_at (0).code != 1); PASS (); }
bool test_big_int_create_2 (Test *test) { BigInt *integer; TITLE (); CATCH (!(integer = big_int_create (0))); CATCH (integer->digits != 1); CATCH (integer->memory[0] != 0); big_int_destroy (integer); PASS (); }
bool test_big_int_mul_function_call_3 (Test *test) { BigInt *a, *b, *to; TITLE (); CATCH (!(a = big_int_create (10000000000000000000ULL))); CATCH (!(b = big_int_create (10000000000000000000ULL))); CATCH (!(to = big_int_create (0))); memory_commit_limit (memory_commit_size () + sizeof (size_t) + sizeof (BigInt) + sizeof (size_t) + 32 + sizeof (size_t) + sizeof (BigInt) + sizeof (size_t) + 32 + sizeof (size_t) + sizeof (BigInt) + sizeof (size_t) + 32 - 1); CATCH (big_int_mul (a, b, to)); CATCH (error_at (0).error != ErrorFunctionCall); CATCH (error_at (0).code != 3); big_int_destroy (a); big_int_destroy (b); big_int_destroy (to); PASS (); }
int term1(big_int *a) { big_int *b = NULL; int n; int result = 0; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (term2(a)) { result = 2; goto done; } while (1) { switch ((int) curr_lex.token) { case '^' : match('^'); if (term2(b)) { result = 3; goto done; } if (is_mod) { if (big_int_powmod(a, b, module, a)) { printf("error during big_int_powmod()\n"); result = 4; goto done; } } else { if (big_int_to_int(b, &n)) { printf("error when converting number [b] to int [n]\n"); result = 5; goto done; } if (big_int_pow(a, n, a)) { printf("error during big_int_pow()\n"); result = 6; goto done; } } continue; default : goto done; } } done: big_int_destroy(b); return result; }
bool test_big_int_equals_string (Test *test) { BigInt *a; TITLE (); CATCH (!(a = big_int_create (123))); CATCH (big_int_equals_string (a, "1234")); CATCH (big_int_equals_string (a, "124")); CATCH (!big_int_equals_string (a, "123")); big_int_destroy (a); PASS (); }
int history_init(void) { int i; for (i = 0; i < HISTORY_SIZE; i++) { history[i] = big_int_create(1); if (history[i] == NULL) { printf("error when creating history[%d]\n", i); return 1; } } history_pos = 0; return 0; }
bool test_big_int_to_value (Test *test) { BigInt *a, *b, *c; uint64_t value; TITLE (); CATCH (!(a = big_int_create (0))); CATCH (!big_int_to_value (a, &value)); CATCH (value != 0); big_int_destroy (a); CATCH (!(a = big_int_create (1))); CATCH (!big_int_to_value (a, &value)); CATCH (value != 1); big_int_destroy (a); CATCH (!(a = big_int_create (10))); CATCH (!big_int_to_value (a, &value)); CATCH (value != 10); big_int_destroy (a); CATCH (!(a = big_int_create (12))); CATCH (!big_int_to_value (a, &value)); CATCH (value != 12); big_int_destroy (a); CATCH (!(a = big_int_create (102))); CATCH (!big_int_to_value (a, &value)); CATCH (value != 102); big_int_destroy (a); CATCH (!(a = big_int_create ((uint64_t)-1))); CATCH (!big_int_to_value (a, &value)); CATCH (value != (uint64_t)-1); big_int_destroy (a); CATCH (!(a = big_int_create ((uint64_t)-1))); CATCH (!(b = big_int_create (1))); CATCH (!(c = big_int_create (0))); CATCH (!big_int_add (a, b, c)); CATCH (big_int_to_value (c, &value)); big_int_destroy (a); big_int_destroy (b); big_int_destroy (c); PASS (); }
bool test_big_int_create_1 (Test *test) { BigInt *integer; char *max = "18446744073709551615"; size_t max_length; size_t i; TITLE (); max_length = string_length (max); CATCH (!(integer = big_int_create ((uint64_t)-1))); CATCH (integer->digits != max_length); for (i = 0; i < max_length; i++) { CATCH (integer->memory[i] != max[i] - '0'); } big_int_destroy (integer); PASS (); }
int expr(big_int *a) { big_int *b = NULL; int result = 0; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (expr1(a)) { result = 2; goto done; } while (1) { switch ((int) curr_lex.token) { case OR1 : case '|' : match(curr_lex.token); if (expr1(b)) { result = 3; goto done; } if (big_int_or(a, b, 0, a)) { printf("error in big_int_or()\n"); result = 4; goto done; } continue; default : goto done; } } done: big_int_destroy(b); return result; }
int term(big_int *a) { big_int *b = NULL; int result = 0; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (term1(a)) { result = 2; goto done; } while (1) { switch ((int) curr_lex.token) { case '*' : match('*'); if (term1(b)) { result = 3; goto done; } if (is_mod) { if (big_int_mulmod(a, b, module, a)) { printf("error in big_int_mulmod()\n"); result = 4; goto done; } } else { if (big_int_mul(a, b, a)) { printf("error in big_int_mul()\n"); result = 5; goto done; } } continue; case '/' : case DIV1 : match(curr_lex.token); if (term1(b)) { result = 6; goto done; } if (is_zero(b)) { printf("division by zero\n"); result = 7; goto done; } if (is_mod) { switch (big_int_divmod(a, b, module, a)) { case 0: break; case 2: printf("GCD(b, modulus) != 1\n"); result = 8; goto done; default : printf("error in big_int_divmod()\n"); result = 8; goto done; } } else { if (big_int_div(a, b, a)) { printf("error in big_int_div()\n"); result = 9; goto done; } } continue; case '%' : case MOD1 : match(curr_lex.token); if (term1(b)) { result = 10; goto done; } if (is_zero(b)) { printf("division by zero\n"); result = 11; goto done; } if (big_int_mod(a, b, a)) { printf("error in big_int_mod()\n"); result = 12; goto done; } continue; default : goto done; } } done: big_int_destroy(b); return result; }
int get_func_args(char *func_name, big_int **args, int args_cnt_min, int args_cnt_max, int *args_cnt) { int result = 0; assert(args_cnt_max <= FUNC_ARGS_SIZE); *args_cnt = 0; if (!match('(')) { printf("expected '(' after function name [%s]\n", func_name); result = 1; goto done; } if (curr_lex.token == ')') { /* empty arguments list */ match(')'); goto done; } /* arguments list is not empty */ while (1) { /* check parameters count, passed to the function */ if (*args_cnt >= args_cnt_max) { printf("function [%s] cannot have more than %d arguments\n", func_name, args_cnt_max); result = 2; goto done; } /* init func_args[func_args_cnt] */ args[*args_cnt] = big_int_create(1); if (args[*args_cnt] == NULL) { printf("error when creating args[%d]\n", *args_cnt); result = 3; goto done; } /* parse next paramter */ if (expr(args[(*args_cnt)++])) { result = 4; goto done; } if (curr_lex.token == ')') { /* end of arguments list */ match(')'); goto done; } /* go to the next argument */ if (!match(',')) { printf("expected ',' or ')' after argument number %d in the function [%s]\n",* args_cnt, func_name); result = 5; goto done; } } done: if (!result && *args_cnt < args_cnt_min) { printf("function [%s] cannot have less than %d arguments\n", func_name, args_cnt_min); result = 7; goto done; } return result; }
int parse(void) { big_int *a = NULL; big_int_str *str = NULL; int result = 0; unsigned int out_base = 10; a = big_int_create(1); str = big_int_str_create(1); if (a == NULL || str == NULL) { printf("error when creating [a] or [str]\n"); result = 1; goto done; } while (1) { if (read_line(CALC_PROMPT)) { break; } if (line_next_char() == '\\') { /* command */ switch (line_next_char()) { case 'q' : /* quit */ printf("quit\n"); goto done; case '?' : case 'h' : /* help */ help(); continue; case 'b' : /* change output base. Default is 10 */ if (sscanf(line.s, "%u", &out_base) != 1) { printf("cannot recogize new base\n"); } if (out_base < 2 || out_base > 36) { printf("wrong value of base. Acceptible value is [2 - 36]\n"); out_base = 10; } else { printf("new base is %u\n", out_base); } continue; case 'm' : /* switch to modular arithmetic */ /* calculate module */ if (lexan()) { continue; } is_mod = 0; /* disable module arithmetic */ if (expr(a)) { /* error when calculating module */ continue; } if (big_int_copy(a, module)) { printf("error when copying number [a] to [module]\n"); continue; } module->sign = PLUS; if (module->len == 1 && module->num[0] < 2) { printf("module must be greater than 1\n"); continue; } is_mod = 1; /* enable module arithmetic */ if (big_int_to_str(module, out_base, str)) { printf("error during converting number to string\n"); continue; } printf("Switching to modular arithmetic. Module is %s\n", str->str); continue; case 'i' : /* switch to integer arithmetic */ is_mod = 0; printf("Switching to integer arithmetic\n"); continue; case 's' : /* show current settings */ puts("Current settings:"); printf("Base: %u\n", out_base); printf("Mode: %s arithmetic\n", is_mod ? "modular (\\m)" : "integer (\\i)"); continue; default : /* unknown command */ printf("unknown command\n"); continue; } } line_prev_char(); /* parse line */ if (lexan() || curr_lex.token == DONE) { continue; } while (!expr(a)) { if (curr_lex.token != ',' && curr_lex.token != DONE) { printf("wrong lexeme [%s]. Token id=%d. Expected ',' or \\n\n", curr_lex.str, curr_lex.token); break; } match(','); /* go to the next expression */ if (is_mod) { if (big_int_absmod(a, module, a)) { printf("error in big_int_absmod()\n"); continue; } } if (big_int_to_str(a, out_base, str)) { printf("error during converting number to string\n"); continue; } /* save result to the history */ if (big_int_copy(a, history[history_pos])) { printf("error when copying number [a] to the history\n"); continue; } /* print result to the display */ history_pos++; printf("$%d = %s\n", history_pos, str->str); if (history_pos >= HISTORY_SIZE) { history_pos = 0; } if (curr_lex.token == DONE) { break; } } } done: big_int_str_destroy(str); big_int_destroy(a); return result; }
int expr3(big_int *a) { big_int *b = NULL; int result = 0; int n; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (expr4(a)) { result = 2; goto done; } while (1) { switch (curr_lex.token) { case SHL : match(SHL); if (expr4(b)) { result = 3; goto done; } if (big_int_to_int(b, &n)) { printf("error when converting number [b] to int [n]\n"); result = 4; goto done; } if (big_int_lshift(a, n, a)) { printf("error in big_int_lshift(a, %d)\n", n); result = 5; goto done; } if (is_mod) { if (big_int_absmod(a, module, a)) { printf("error in big_int_absmod()\n"); result = 6; goto done; } } continue; case SHR : match(SHR); if (expr4(b)) { result = 7; goto done; } if (big_int_to_int(b, &n)) { printf("error when converting number [b] to int [n]\n"); result = 8; goto done; } if (big_int_rshift(a, n, a)) { printf("error in big_int_rshift(a, %d)\n", n); result = 9; goto done; } if (is_mod) { if (big_int_absmod(a, module, a)) { printf("error in big_int_absmod()\n"); result = 10; goto done; } } continue; default : goto done; } } done: big_int_destroy(b); return result; }
int expr4(big_int *a) { big_int *b = NULL; int result = 0; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (term(a)) { result = 2; goto done; } while (1) { switch ((int) curr_lex.token) { case '+' : match('+'); if (term(b)) { result = 3; goto done; } if (is_mod) { if (big_int_addmod(a, b, module, a)) { printf("error in big_int_addmod()\n"); result = 4; goto done; } } else { if (big_int_add(a, b, a)) { printf("error in big_int_add()\n"); result = 5; goto done; } } continue; case '-' : match('-'); if (term(b)) { result = 6; goto done; } if (is_mod) { if (big_int_submod(a, b, module, a)) { printf("error in big_int_submod()\n"); result = 7; goto done; } } else { if (big_int_sub(a, b, a)) { printf("error in big_int_sub()\n"); result = 8; goto done; } } continue; default : goto done; } } done: big_int_destroy(b); return result; }