/*---------------------------------------------------------- * HTBLA-Leonding / Class: 2IHIF * --------------------------------------------------------- * Exercise Number: 0 * Title: Pyramid of Numbers * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Calculates a pyramid of numbers, i.e., it multiplies a big * integer by the number 2, its result by 3, etc. and then * returns to the original value by subsequently dividing, * again starting by 2, 3, etc. * ---------------------------------------------------------- */ #include #include /// The maximum number of digits allowed in a big int. #define MAX_DIGITS 80 /** BigInt represents an integer number which can have MAX_DIGITS digits *** @see MAX_DIGITS */ struct BigInt { /** number of digits of the big int. */ int digits_count; /** array of digits of big int. */ 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 *** against a character not between '0' and '9' the conversion stops *** at this point. *** @param *str The string to be converted. *** @param len Number of characters in string to be converted. *** @param *big_int The converted string now as BigInt. * @return The number of characters converted. */ int strtobig_int(const char* str, int len, struct BigInt* big_int) { reset_big_int(big_int, -1); int conversions = 0; int j = 0; for (int i = len - 1; i >= 0; i--) { int big_int_position = MAX_DIGITS - j - 1; int converted = str[i] - '0'; if (converted >= 0 && converted <= 9) { big_int->the_int[big_int_position] = converted; conversions++; } else { big_int->digits_count = conversions; //reset_big_int(big_int, conversions); return conversions; } j++; } big_int->digits_count = conversions; //reset_big_int(big_int, conversions); return conversions; } /** print_big_int() prints a BigInt. *** @param *big_int The BigInt to be printed. */ void print_big_int(const struct BigInt *big_int) { for (int i = MAX_DIGITS - big_int->digits_count; i < MAX_DIGITS; i++) { printf("%d", big_int->the_int[i]); } } /** multiply() multiplies a BigInt by an int. *** @param big_int The BigInt to be multiplied. *** @param factor The int value which is multiplied by BigInt. *** @param *big_result The result of the multiplication. */ void multiply(const struct BigInt* big_int, int factor, struct BigInt* big_result) { //set everything in the result to 0 reset_big_int(big_result, -1); //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. *** @param big_int The BigInt to be divided. *** @param divisor The int value by which we want to devide big_int. *** @param *big_result The result of the division. */ void divide(const struct BigInt* big_int, int divisor, struct BigInt* big_result) { //set everything in the result to 0 reset_big_int(big_result, -1); //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 for (int i = MAX_DIGITS - big_int->digits_count; i < MAX_DIGITS; i++) { int result = (big_int->the_int[i] + big_result->the_int[i]) / divisor; int remainder = big_int->the_int[i] + big_result->the_int[i] - (result * divisor); big_result->the_int[i + 1] = remainder * 10; big_result->the_int[i] = result; } set_big_int_length(big_result); } /** copy_big_int() copies a BigInt to another BigInt. *** @param from The source where we want to copy from. *** @param *to The target where we want to copy to. */ void copy_big_int(const struct BigInt* from, struct BigInt* to) { to->digits_count = from->digits_count; for (int i = 0; i < MAX_DIGITS; i++) { to->the_int[i] = from->the_int[i]; } } /** *** main() reads the base number from which the pyramid has to be calculated *** into an array of char. The max. length of this number is MAX_DIGITS. *** The number is checked to contain only digits. If not the program exits. *** Then the inputted number is converted into a big int by calling the *** function strtobig_int(). *** After the conversion the tower is calculated by calling the functions *** multiply(), print_big_int(), and copy_big_int() consecutively from 2 to *** 9 and then again with divide() instead of multiply() from 2 to 9. *** */ int main(int argc, char* argv[]) { printf("Pyramid of Numbers\n\n"); printf("Please enter a number: "); char input_str[MAX_DIGITS]; scanf("%s", input_str); struct BigInt original_big_int; int len = strlen(input_str); reset_big_int(&original_big_int, -1); strtobig_int(input_str, len, &original_big_int); struct BigInt changed_big_int; copy_big_int(&original_big_int, &changed_big_int); //multiply for (int i = 2; i < 10; i++) { //create temp BigInt & multiply struct BigInt temp; multiply(&changed_big_int, i, &temp); print_big_int(&changed_big_int); printf(" * %d = ", i); print_big_int(&temp); printf("\n"); copy_big_int(&temp, &changed_big_int); } //divide for (int i = 9; i > 1; i--) { //create temp BigInt & divide struct BigInt temp; divide(&changed_big_int, i, &temp); print_big_int(&changed_big_int); printf(" / %d = ", i); print_big_int(&temp); printf("\n"); copy_big_int(&temp, &changed_big_int); } return 0; }