Last active
March 27, 2024 23:44
-
-
Save NoahTheBaker/be9dc1162c11fd87780126c396c01444 to your computer and use it in GitHub Desktop.
Francesco146's Fibonacci Prog (Edited)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Calculate Fibonacci Numbers | |
// Public Domain | |
// https://creativecommons.org/publicdomain/zero/1.0/ | |
#include <ctype.h> | |
#include <stdio.h> | |
#include <gmp.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <time.h> | |
/* * | |
* Here's some time I got: | |
* fib(1): 0.000009 seconds | |
* fib(10): 0.000009 seconds | |
* fib(100): 0.000009 seconds | |
* fib(1 000): 0.000011 seconds | |
* fib(10 000): 0.000030 seconds | |
* fib(100 000): 0.000193 seconds | |
* fib(1 000 000): 0.004409 seconds | |
* fib(10 000 000): 0.047819 seconds | |
* fib(100 000 000): 0.704643 seconds | |
* fib(1 000 000 000): 8.852119 seconds | |
*/ | |
int main(int argc, char *argv[]) | |
{ | |
_Bool need_result = 0; | |
// Get User Input | |
if (argc < 2 || argc > 3) | |
{ | |
fprintf(stderr, "Usage: %s <number> [--need-result]\n", argv[0]); | |
return EXIT_FAILURE; | |
} | |
if (argc == 3 && strcmp(argv[2], "--need-result") == 0) | |
need_result = 1; | |
long count = strtol(argv[1], NULL, 10); | |
// Setup GMP | |
mpz_t a, b, p, q; | |
mpz_init_set_ui(a, 1); | |
mpz_init_set_ui(b, 0); | |
mpz_init_set_ui(p, 0); | |
mpz_init_set_ui(q, 1); | |
mpz_t tmp; | |
mpz_init(tmp); | |
// Start timing | |
const clock_t start_time = clock(); | |
while (count > 0) | |
{ | |
if (count & 1) | |
{ | |
mpz_mul(tmp, q, q); | |
mpz_mul(q, q, p); | |
mpz_mul_2exp(q, q, 1); | |
mpz_add(q, q, tmp); | |
mpz_mul(p, p, p); | |
mpz_add(p, p, tmp); | |
count >>= 1; | |
} | |
else | |
{ | |
mpz_mul(tmp, a, q); | |
mpz_mul(a, a, p); | |
mpz_addmul(a, b, q); | |
mpz_add(a, a, tmp); | |
mpz_mul(b, b, p); | |
mpz_add(b, b, tmp); | |
count -= 1; | |
} | |
} | |
// End timing | |
const clock_t end_time = clock(); | |
if (end_time == (clock_t){-1}) | |
{ | |
fprintf(stderr, "Error end_time clock()\n"); | |
return EXIT_FAILURE; | |
} | |
// Print time taken | |
const double time_taken = ((double) (end_time - start_time)) / (double) CLOCKS_PER_SEC; | |
char buffer[100]; | |
int len = sprintf(buffer, "fib(%s): %f seconds\n", argv[1], time_taken); | |
if (write(STDOUT_FILENO, buffer, len) == -1) | |
{ | |
fprintf(stderr, "Error write()\n"); | |
return EXIT_FAILURE; | |
} | |
if (fflush(stdout) == EOF) | |
return EXIT_FAILURE; | |
// Check if --need-result option is provided | |
if (need_result) | |
{ | |
// open file to write the result (out.txt) | |
FILE *fp; | |
fp = fopen("out.txt", "w"); | |
if (fp == NULL) | |
{ | |
fprintf(stderr, "Error opening file\n"); | |
return EXIT_FAILURE; | |
} | |
mpz_out_str(fp, 10, b); | |
} | |
//NTB | |
mpz_out_str(stdout, 10, b); | |
//NTB | |
// Cleanup | |
mpz_clear(a); | |
mpz_clear(b); | |
mpz_clear(p); | |
mpz_clear(q); | |
mpz_clear(tmp); | |
return EXIT_SUCCESS; | |
} |
@g1rly-c0d3r I'm pretty sure those were Francesco's times but I'll re-run them for you on my Ryzen 5700x with 48gb 3000mhz RAM (Using my other Fib program here) with only the digits counted.
./fib.exe 1
Number of Digits: 1
Calculation Time: 0.0000 seconds
Total Time Taken: 0.0010 seconds
./fib.exe 10
Number of Digits: 2
Calculation Time: 0.0000 seconds
Total Time Taken: 0.0030 seconds
./fib.exe 100
Number of Digits: 21 (10 Shown, 11 in .....)
Calculation Time: 0.0000 seconds
Total Time Taken: 0.0030 seconds
./fib.exe 1000
Number of Digits: 209 (10 Shown, 199 in .....)
Calculation Time: 0.0000 seconds
Total Time Taken: 0.0040 seconds
./fib.exe 10000
Number of Digits: 2090 (10 Shown, 2080 in .....)
Calculation Time: 0.0000 seconds
Total Time Taken: 0.0030 seconds
./fib.exe 100000
Number of Digits: 20899 (10 Shown, 20889 in .....)
Calculation Time: 0.0010 seconds
Total Time Taken: 0.0050 seconds
./fib.exe 1000000
Number of Digits: 208988 (10 Shown, 208978 in .....)
Calculation Time: 0.0070 seconds
Total Time Taken: 0.0190 seconds
./fib.exe 10000000
Number of Digits: 2089877 (10 Shown, 2089867 in .....)
Calculation Time: 0.1030 seconds
Total Time Taken: 0.2900 seconds
./fib.exe 100000000
Number of Digits: 20898764 (10 Shown, 20898754 in .....)
Calculation Time: 1.5770 seconds
Total Time Taken: 4.4440 seconds
./fib.exe 1000000000
Number of Digits: 208987640 (10 Shown, 208987630 in .....)
Calculation Time: 18.9060 seconds
Total Time Taken: 56.5100 seconds
@g1rly-c0d3r Looks great! Much faster output now.
Only difference is yours shows n-1 instead of n shown characters (the character right after the . . . . . ) but that was a problem with an earlier version of mine as well :). awesome work cleaning stuff up!
@NoahTheBaker I had a lot of fun! I ended up translating this algorithm to fortran (mostly to learn more about the language) and that program ended up being slower, but I did learn a lot more about the gnu compiler collection as well as managing libraries from doing this. :3
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
what are your PC specs? the times mean nothing without your specs :3