diff options
Diffstat (limited to 'main.c')
| -rwxr-xr-x | main.c | 92 |
1 files changed, 92 insertions, 0 deletions
@@ -0,0 +1,92 @@ +// main.c - Moving average calculator using ts library +// Computes a simple moving average over configurable period and displays results. + +#include <errno.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define TS_IMPLEMENTATION +#include "ts.h" + +#define BUFFER_SIZE 100 +#define DISPLAY_N 20 + +static void usage(const char *prog) +{ + fprintf(stderr, "Usage: %s [period]\n", prog); + fprintf(stderr, " period: moving average window (1-%d, default: 10)\n", BUFFER_SIZE); +} + +int main(int argc, char *argv[]) { + uint_t period = 10; + if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { + usage(argv[0]); + return 0; + } + if (argc > 1) { + char *endptr = NULL; + errno = 0; + long val = strtol(argv[1], &endptr, 10); + if (endptr == argv[1] || *endptr != '\0' || errno == ERANGE) { + fprintf(stderr, "Error: invalid period '%s'\n", argv[1]); + usage(argv[0]); + return 1; + } + if (val < 1 || val > BUFFER_SIZE) { + fprintf(stderr, "Error: period must be between 1 and %d\n", BUFFER_SIZE); + usage(argv[0]); + return 1; + } + period = (uint_t)val; + } + if (period == 0 || period > BUFFER_SIZE) { + fprintf(stderr, "Error: period must be between 1 and %d\n", BUFFER_SIZE); + usage(argv[0]); + return 1; + } + + fp_t input[BUFFER_SIZE]; + fp_t output[BUFFER_SIZE]; + for (int_t i = 0; i < (int_t)BUFFER_SIZE; i++) { + output[i] = 0; + } + + if (!ts_fill(input, BUFFER_SIZE, 0, (fp_t)BUFFER_SIZE)) { + fprintf(stderr, "ts_fill failed\n"); + return 1; + } + + fp_t * const y[1] = { output }; + fp_t const * const x[1] = { input }; + + ts_constant_t c; + memset(&c, 0, sizeof(c)); + *(uint_t *)c.data = period; + int ret = ts_average(y, 1, x, 1, BUFFER_SIZE, &c); + if (ret == -1) { + fprintf(stderr, "ts_average failed\n"); + return 1; + } + + /* Validate output: first valid value is at index period-1 */ + uint_t offset = period - 1; + if (offset >= BUFFER_SIZE) { + fprintf(stderr, "error: period exceeds buffer size\n"); + return 1; + } + + /* Clamp display range to valid output */ + uint_t display_end = DISPLAY_N < BUFFER_SIZE ? DISPLAY_N : BUFFER_SIZE; + if (offset >= display_end) { + fprintf(stderr, "warning: period (%" TS_PRIuint ") >= display count (%" TS_PRIuint "), showing available data\n", period, display_end); + display_end = BUFFER_SIZE; + } + + for (uint_t i = offset; i < display_end; i++) { + printf("input[%" TS_PRIuint "] = %f SMA[%" TS_PRIuint "] = %f\n", i, input[i], i, output[i]); + } + + return 0; +} |