Repaired multiply and divide functions & added 2 extra functions

This commit is contained in:
marc 2024-10-22 16:22:22 +02:00
parent 20b90a2156
commit 3762f6383d
3 changed files with 97 additions and 40 deletions

28
assignment/.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

Binary file not shown.

View file

@ -29,6 +29,38 @@ struct BigInt {
unsigned int the_int[MAX_DIGITS]; unsigned int the_int[MAX_DIGITS];
}; };
/** reset_big_int sets content to 0
*** @param *big_int The BigInt to be reset
*** @param startPos The start position where the reset shall begin
**/
void reset_big_int(struct BigInt *big_int, int startPos) {
if (startPos < 0 || startPos > MAX_DIGITS) {
startPos = 0;
}
startPos = MAX_DIGITS - startPos;
for (int i = startPos; i >= 0; i--)
{
big_int->the_int[i] = 0;
}
big_int->digits_count = 0;
}
/** set_big_int_length determines the length and sets it
*** @param *big_int The BigInt to determine the length
**/
void set_big_int_length(struct BigInt *big_int)
{
for (int i = 0; i < MAX_DIGITS; i++)
{
if(big_int->the_int[i] != 0)
{
big_int->digits_count = MAX_DIGITS - i;
return;
}
}
}
/** strtobig_int converts a string into a BigInt. If strtobig_int runs /** strtobig_int converts a string into a BigInt. If strtobig_int runs
*** against a character not between '0' and '9' the conversion stops *** against a character not between '0' and '9' the conversion stops
*** at this point. *** at this point.
@ -38,22 +70,28 @@ struct BigInt {
* @return The number of characters converted. * @return The number of characters converted.
*/ */
int strtobig_int(const char* str, int len, struct BigInt* big_int) { int strtobig_int(const char* str, int len, struct BigInt* big_int) {
reset_big_int(big_int, -1);
int conversions = 0; int conversions = 0;
for (int i = 0; i < len; i++) int j = 0;
for (int i = len - 1; i >= 0; i--)
{ {
int big_int_position = MAX_DIGITS - j - 1;
int converted = str[i] - '0'; int converted = str[i] - '0';
if (converted >= 0 && converted <= 9) if (converted >= 0 && converted <= 9)
{ {
big_int->the_int[conversions] = converted; big_int->the_int[big_int_position] = converted;
conversions++; conversions++;
} }
else else
{ {
big_int->digits_count = conversions; big_int->digits_count = conversions;
//reset_big_int(big_int, conversions);
return conversions; return conversions;
} }
j++;
} }
big_int->digits_count = conversions; big_int->digits_count = conversions;
//reset_big_int(big_int, conversions);
return conversions; return conversions;
} }
@ -61,7 +99,7 @@ int strtobig_int(const char* str, int len, struct BigInt* big_int) {
*** @param *big_int The BigInt to be printed. *** @param *big_int The BigInt to be printed.
*/ */
void print_big_int(const struct BigInt *big_int) { void print_big_int(const struct BigInt *big_int) {
for (int i = 0; i < big_int->digits_count; i++) for (int i = MAX_DIGITS - big_int->digits_count; i < MAX_DIGITS; i++)
{ {
printf("%d", big_int->the_int[i]); printf("%d", big_int->the_int[i]);
} }
@ -73,25 +111,20 @@ void print_big_int(const struct BigInt *big_int) {
*** @param *big_result The result of the multiplication. *** @param *big_result The result of the multiplication.
*/ */
void multiply(const struct BigInt* big_int, int factor, struct BigInt* big_result) { void multiply(const struct BigInt* big_int, int factor, struct BigInt* big_result) {
int overflow = 0; //set everything in the result to 0
int sizeOfResult = big_int->digits_count + 1; reset_big_int(big_result, -1);
char big_str_result[sizeOfResult];
for(int i = 0; i < big_int->digits_count; i++)
{
int result = big_int->the_int[i] * factor + overflow;
if (result > 9)
{
overflow = result / 10;
result = result - overflow;
}
big_str_result[i] = result + '0';
}
if (big_str_result[sizeOfResult - 1] == '0')
{
sizeOfResult--;
}
strtobig_int(big_str_result, sizeOfResult, big_result); //no global overflow needed as it automatically saves it in the next place
//no need for '()' braces in the calculation, but used for a better view
for (int i = MAX_DIGITS - 1; i >= MAX_DIGITS - big_int->digits_count; i--) {
int result = (big_int->the_int[i] * factor) + big_result->the_int[i];
int overflow = result / 10;
int result_for_i = result - overflow * 10;
big_result->the_int[i] = result_for_i;
big_result->the_int[i - 1] = overflow;
}
set_big_int_length(big_result);
} }
/** divide() multiplies a BigInt by an int. /** divide() multiplies a BigInt by an int.
@ -100,24 +133,19 @@ void multiply(const struct BigInt* big_int, int factor, struct BigInt* big_resul
*** @param *big_result The result of the division. *** @param *big_result The result of the division.
*/ */
void divide(const struct BigInt* big_int, int divisor, struct BigInt* big_result) { void divide(const struct BigInt* big_int, int divisor, struct BigInt* big_result) {
int remainder = 0; //set everything in the result to 0
int sizeOfResult = big_int->digits_count; reset_big_int(big_result, -1);
char str_result[sizeOfResult];
for (int i = 0; i < big_int->digits_count; i++) //no global remainder needed as the remainder is automatically saved in the big_result
{ //no need for '()' braces in the calculation, but used for a better view
int calculate = remainder * 10; for (int i = MAX_DIGITS - big_int->digits_count; i < MAX_DIGITS; i++) {
calculate += big_int->the_int[i]; int result = (big_int->the_int[i] + big_result->the_int[i]) / divisor;
int result = calculate / divisor; int remainder = big_int->the_int[i] + big_result->the_int[i] - (result * divisor);
if (result == 0) {
remainder = big_int->the_int[i]; big_result->the_int[i + 1] = remainder * 10;
} big_result->the_int[i] = result;
str_result[i] = result + '0';
} }
if (str_result[sizeOfResult - 1] == '0') set_big_int_length(big_result);
{
sizeOfResult--;
}
strtobig_int(str_result, sizeOfResult, big_result);
} }
/** copy_big_int() copies a BigInt to another BigInt. /** copy_big_int() copies a BigInt to another BigInt.
@ -126,7 +154,7 @@ void divide(const struct BigInt* big_int, int divisor, struct BigInt* big_result
*/ */
void copy_big_int(const struct BigInt* from, struct BigInt* to) { void copy_big_int(const struct BigInt* from, struct BigInt* to) {
to->digits_count = from->digits_count; to->digits_count = from->digits_count;
for (int i = 0; i < from->digits_count; i++) { for (int i = 0; i < MAX_DIGITS; i++) {
to->the_int[i] = from->the_int[i]; to->the_int[i] = from->the_int[i];
} }
} }
@ -152,6 +180,7 @@ int main(int argc, char* argv[])
struct BigInt original_big_int; struct BigInt original_big_int;
int len = strlen(input_str); int len = strlen(input_str);
reset_big_int(&original_big_int, -1);
strtobig_int(input_str, len, &original_big_int); strtobig_int(input_str, len, &original_big_int);
struct BigInt changed_big_int; struct BigInt changed_big_int;
@ -175,7 +204,7 @@ int main(int argc, char* argv[])
//divide //divide
for (int i = 9; i > 1; i--) for (int i = 9; i > 1; i--)
{ {
//create temp BigInt & multiply //create temp BigInt & divide
struct BigInt temp; struct BigInt temp;
divide(&changed_big_int, i, &temp); divide(&changed_big_int, i, &temp);