|
1 | 1 | /************************************************************************* |
2 | 2 | * big-fac.c |
3 | | - * |
4 | | - * Project: Big-Numbers Factorial Simple Calculator |
5 | | - * Author: Janderson Gomes |
6 | | - * Blog: artientista.blogspot.com |
7 | | - * E-mail: dparicarana@gmail.com |
| 3 | + * |
| 4 | + * Project: Big-Positive-Numbers Factorial Calculator |
| 5 | + * Author: @jndgomes |
8 | 6 | * |
9 | 7 | * Description: |
10 | | - * A simple program to calculate the factorial of very large numbers, |
11 | | - * capable of handling results with tens of thousands of digits. |
12 | | - * |
| 8 | + * This program calculates the factorial of very large numbers, capable of |
| 9 | + * handling results with tens of thousands of digits. The number of digits |
| 10 | + * is estimated using Stirling's approximation. |
| 11 | + * |
13 | 12 | * Disclaimer: |
14 | | - * THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR |
15 | | - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
16 | | - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
17 | | - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
18 | | - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
19 | | - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
20 | | - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
21 | | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
22 | | - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
23 | | - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
24 | | - * POSSIBILITY OF SUCH DAMAGE. |
| 13 | + * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. |
| 14 | + * |
25 | 15 | ************************************************************************/ |
26 | 16 |
|
27 | 17 | #include <stdio.h> |
| 18 | +#include <math.h> |
28 | 19 |
|
29 | | -// Maximum number of digits the result can hold (e.g., up to 10,000!) |
30 | | -#define MAX_DIGITS_NUMBER 40000 /* Adjust based on README instructions */ |
31 | | - |
32 | | -/* Note: This algorithm is not optimized for calculating the factorial |
33 | | - * of arbitrary numbers. The variable MAX_DIGITS_NUMBER must be adjusted |
34 | | - * to ensure enough memory is allocated for the result. |
35 | | - */ |
36 | | - |
37 | | -int main() |
38 | | -{ |
39 | | - // Array to store the digits of the result |
40 | | - char result[MAX_DIGITS_NUMBER]; |
| 20 | +int main() { |
| 21 | + // Variable to store the estimated maximum number of digits |
| 22 | + int MAX_DIGITS_NUMBER; |
41 | 23 |
|
42 | 24 | // Auxiliary variables |
43 | 25 | int i, j, number, dcounter, carry, tmp; |
44 | 26 |
|
45 | 27 | // User input |
46 | | - printf("Factorial Simple Calculator\n\n"); |
47 | | - printf("Enter a number (e.g., 10000): "); |
| 28 | + printf("Large Number Factorial Calculator\n\n"); |
| 29 | + printf("Enter a number (e.g., 1993): "); |
48 | 30 | scanf("%d", &number); |
49 | 31 |
|
50 | | - // Initialize the result array with the first digit (1) |
| 32 | + // Estimate the number of digits in the factorial using Stirling's formula |
| 33 | + MAX_DIGITS_NUMBER = (int)( |
| 34 | + (log(2 * M_PI) / 2 + log(number) / 2 + number * (log(number) - 1)) / log(10) |
| 35 | + ) + 1; |
| 36 | + |
| 37 | + // Allocate an array to hold the digits of the result |
| 38 | + char result[MAX_DIGITS_NUMBER]; |
| 39 | + |
| 40 | + // Initialize the result with the value 1 (the factorial of 0 or 1) |
51 | 41 | result[0] = 1; |
52 | 42 |
|
53 | | - // Initialize the digit counter (starting with 1 digit) |
| 43 | + // Initialize the digit counter and carry-over variable |
54 | 44 | dcounter = 1; |
55 | | - |
56 | | - // Initialize the carry to zero |
57 | 45 | carry = 0; |
58 | 46 |
|
59 | | - // Empty line for clarity |
| 47 | + // Print an empty line for formatting |
60 | 48 | puts(""); |
61 | 49 |
|
62 | | - // Loop through numbers from 1 to the input number |
63 | | - for (i = 1; i <= number; i++) |
64 | | - { |
65 | | - // Multiply each digit in the result array by the current number |
66 | | - for (j = 0; j < dcounter; j++) |
67 | | - { |
68 | | - tmp = result[j] * i + carry; // Multiply and add carry |
69 | | - result[j] = tmp % 10; // Store the single digit |
70 | | - carry = tmp / 10; // Update the carry |
| 50 | + // Main factorial computation loop |
| 51 | + for (i = 1; i <= number; i++) { |
| 52 | + for (j = 0; j < dcounter; j++) { |
| 53 | + // Multiply the current digit by i and add the carry |
| 54 | + tmp = result[j] * i + carry; |
| 55 | + // Update the current digit |
| 56 | + result[j] = tmp % 10; |
| 57 | + // Update the carry for the next digit |
| 58 | + carry = tmp / 10; |
71 | 59 | } |
72 | 60 |
|
73 | | - // Handle any leftover carry |
74 | | - while (carry > 0) |
75 | | - { |
| 61 | + // Add remaining carry digits to the result array |
| 62 | + while (carry > 0) { |
76 | 63 | result[dcounter] = carry % 10; |
77 | 64 | carry /= 10; |
78 | 65 | dcounter++; |
79 | 66 | } |
80 | 67 |
|
81 | | - // Display progress to the user |
| 68 | + // Display progress (number of digits calculated so far) |
82 | 69 | printf("\r%d digits calculated...", dcounter); |
83 | 70 | } |
84 | 71 |
|
85 | | - // Empty line for output formatting |
| 72 | + // Print an empty line for formatting |
86 | 73 | puts(""); |
87 | 74 |
|
88 | 75 | // Display the factorial result |
89 | 76 | printf("\nFactorial of %d is:\n\n", number); |
90 | | - for (i = dcounter - 1; i >= 0; i--) |
91 | | - { |
| 77 | + for (i = dcounter - 1; i >= 0; i--) { |
92 | 78 | printf("%d", result[i]); |
93 | 79 | } |
94 | 80 |
|
95 | | - // Return successful exit code |
| 81 | + // Exit the program successfully |
96 | 82 | return 0; |
97 | 83 | } |
0 commit comments