summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamilsk <alive6863@gmail.com>2025-09-13 17:57:02 +0300
committerNamilsk <alive6863@gmail.com>2025-09-13 17:58:17 +0300
commit8465c253c561c08bfaa6f75b29b9798619bf7be3 (patch)
tree6b7e8bfcdaef039ff89146003d18d0c4f4f59152
parent7978ca7da34f7e9665f30077cce62d9cb06f752f (diff)
Implemented args: -i -d
-rw-r--r--.gitignore2
-rw-r--r--CMakeLists.txt17
-rwxr-xr-xbuild.sh3
-rw-r--r--src/config.c0
-rw-r--r--src/config.h4
-rw-r--r--src/main.c189
-rwxr-xr-xtpibin0 -> 16272 bytes
7 files changed, 215 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 845cda6..2c21074 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,3 +53,5 @@ dkms.conf
# debug information files
*.dwo
+releases/
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..a2d0046
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall -Wextra -Werror -v")
+
+project(termpi)
+
+set(CMAKE_C_STANDART 99)
+set(CC clang)
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(MPFR REQUIRED mpfr)
+
+set(SOURCES
+ main.c
+ config.c
+)
+
+add_executable(${PROJECT_NAME} ${MPFR_LIBRARIES})
+
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..093eefd
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+gcc -v -Wall -Wextra -Werror -lm -lmpfr -lgmp -I/usr/local/include -L/usr/local/lib src/main.c -o tpi-v2
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/config.c
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..cafea73
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,4 @@
+#include <stdio.h>
+
+void parse_config(char path[]);
+
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..c089223
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,189 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpfr.h>
+#include <math.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+
+// -lmpfr -lgmp -lm -Wall -Wextra -Werror
+
+// Gauss-Legendre method
+int calculate_pi(int len, bool infinite_mode, int delay_ms) {
+ mp_bitcnt_t precision = (mp_bitcnt_t)(len * 3.321928094 + 100); // Увеличил запас точности
+
+ mpfr_t a, b, t, p, a_next, t_tmp, p_tmp, pi;
+ mpfr_inits2(precision, a, b, t, p, a_next, t_tmp, p_tmp, pi, (mpfr_ptr)0);
+
+
+ mpfr_set_d(a, 1.0, MPFR_RNDN);
+ mpfr_sqrt_ui(b, 2, MPFR_RNDN); // b = sqrt(2)
+ mpfr_ui_div(b, 1, b, MPFR_RNDN); // b = 1/sqrt(2)
+ mpfr_set_d(t, 0.25, MPFR_RNDN);
+ mpfr_set_d(p, 1.0, MPFR_RNDN);
+
+ int iterations = (int)(log2(len)) + 3;
+
+ for (int i = 0; i < iterations; i++) {
+ // a_next = (a + b)/2
+ mpfr_add(a_next, a, b, MPFR_RNDN);
+ mpfr_div_2ui(a_next, a_next, 1, MPFR_RNDN);
+
+ // b = sqrt(a * b)
+ mpfr_mul(b, a, b, MPFR_RNDN);
+ mpfr_sqrt(b, b, MPFR_RNDN);
+
+ // t_tmp = t - p * (a - a_next)^2
+ mpfr_sub(t_tmp, a, a_next, MPFR_RNDN);
+ mpfr_sqr(t_tmp, t_tmp, MPFR_RNDN);
+ mpfr_mul(t_tmp, p, t_tmp, MPFR_RNDN);
+ mpfr_sub(t, t, t_tmp, MPFR_RNDN);
+
+ // p = 2 * p
+ mpfr_mul_2ui(p, p, 1, MPFR_RNDN);
+
+ // a = a_next
+ mpfr_set(a, a_next, MPFR_RNDN);
+ }
+
+ // π = (a + b)^2 / (4 * t)
+ mpfr_add(pi, a, b, MPFR_RNDN);
+ mpfr_sqr(pi, pi, MPFR_RNDN);
+ mpfr_mul_ui(t, t, 4, MPFR_RNDN);
+ mpfr_div(pi, pi, t, MPFR_RNDN);
+
+ if (!infinite_mode) {
+
+ printf("π = ");
+ mpfr_out_str(stdout, 10, len, pi, MPFR_RNDN);
+ printf("\n");
+ } else {
+
+ mpfr_exp_t exp;
+ char *pi_str;
+
+ pi_str = mpfr_get_str(NULL, &exp, 10, 0, pi, MPFR_RNDN);
+
+ if (pi_str == NULL) {
+ fprintf(stderr, "Error occurred while translating pi to char\n");
+ mpfr_clears(a, b, t, p, a_next, t_tmp, p_tmp, pi, (mpfr_ptr)0);
+ return 1;
+ }
+
+
+ if (exp == 1) {
+
+ printf("π = %c", pi_str[0]);
+ fflush(stdout);
+ if (delay_ms > 0) {
+ struct timespec ts;
+ ts.tv_sec = delay_ms / 1000;
+ ts.tv_nsec = (delay_ms % 1000) * 1000000L;
+ nanosleep(&ts, NULL);
+ }
+
+ printf(".");
+ fflush(stdout);
+ if (delay_ms > 0) {
+ struct timespec ts;
+ ts.tv_sec = delay_ms / 1000;
+ ts.tv_nsec = (delay_ms % 1000) * 1000000L;
+ nanosleep(&ts, NULL);
+ }
+
+
+ for (int i = 1; pi_str[i] != '\0'; i++) {
+ printf("%c", pi_str[i]);
+ fflush(stdout);
+ if (delay_ms > 0) {
+ struct timespec ts;
+ ts.tv_sec = delay_ms / 1000;
+ ts.tv_nsec = (delay_ms % 1000) * 1000000L;
+ nanosleep(&ts, NULL);
+ }
+ }
+ printf("\n");
+ } else {
+
+ printf("π = 0.%se%ld\n", pi_str, (long)exp);
+ }
+
+ mpfr_free_str(pi_str);
+ }
+
+ mpfr_clears(a, b, t, p, a_next, t_tmp, p_tmp, pi, (mpfr_ptr)0);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int delay_ms = 500;
+ int count = 0;
+ bool infinite_mode = false;
+ bool help = false;
+ int opt;
+
+
+ while ((opt = getopt(argc, argv, "ihc:t:")) != -1) {
+ switch (opt) {
+ case 'i':
+ infinite_mode = true;
+ break;
+ case 'h':
+ help = true;
+ break;
+ case 'c':
+ count = atoi(optarg);
+ if(count <= 0) {
+ fprintf(stderr, "Invalid value for -c. Must be a positive integer.\n");
+ return 1;
+ }
+ break;
+ case 't':
+ delay_ms = atoi(optarg);
+ if(delay_ms < 0) {
+ fprintf(stderr, "Invalid value for -t. Must be a non-negative integer.\n");
+ return 1;
+ }
+ break;
+ case '?':
+
+ if (optopt == 'c' || optopt == 't') {
+ fprintf(stderr, "Option -%c requires an argument.\n", optopt);
+ } else {
+ fprintf(stderr, "Unknown option: -%c\n", optopt);
+ }
+ return 1;
+ default:
+ abort();
+ }
+ }
+
+ if (help) {
+ printf("tpi - C-written, MPFR-based CLI program for calculating π\n");
+ printf("ARGS:\n");
+ printf(" -h - Showing this message.\n");
+ printf(" -i - Infinitely outputs the digits of pi one at a time.\n");
+ printf(" -c=int - Outputs the number of digits of pi passed to the argument.\n");
+ printf(" -t=int - Setting the output speed in -i mode (milliseconds). The default value is 500.\n");
+ return 0;
+ }
+
+
+ if (infinite_mode) {
+
+ int internal_precision = 1000000;
+ if(count > 0 && count < internal_precision) {
+ internal_precision = count;
+ }
+
+ calculate_pi(internal_precision, true, delay_ms);
+ } else if (count > 0) {
+
+ calculate_pi(count, false, 0);
+ } else {
+
+ calculate_pi(500, false, 0);
+ }
+
+ return 0;
+}
diff --git a/tpi b/tpi
new file mode 100755
index 0000000..cdd3cce
--- /dev/null
+++ b/tpi
Binary files differ