X-Git-Url: https://git.llucax.com/z.facultad/75.42/euler.git/blobdiff_plain/e8be4543c7b27b4f68517e8b12acc895388997f2..cd5e734a119e8827615d5a51820d048f32efdcae:/tp1.c diff --git a/tp1.c b/tp1.c index 7706605..d68bb58 100644 --- a/tp1.c +++ b/tp1.c @@ -15,9 +15,37 @@ * $Id$ */ -/* Cabecera del TP. */ -#include "tp1.h" +#include "carga.h" +#include "calculo.h" +#include "grafico.h" +/* Para utilizar printf() y stderr */ +#include +/* Para utilizar EXIT_SUCCES y EXIT_FAILURE */ +#include +/** Tiempo inicial por omisión. */ +#define DEFAULT_T0 0.0 + +/** Tiempo final por omisión. */ +#define DEFAULT_TF 70.0 + +/** Valor inicial de la función por omisión. */ +#define DEFAULT_F0 0.0 + +/** Valor del pas de iteración por omisión. */ +#define DEFAULT_PASO 1.0 + +/** Caracter usado para dibujar un punto por omisión. */ +#define DEFAULT_PUNTO '*' + +/** Caracter usado para dibujar un punto blanco por omisión. */ +#define DEFAULT_BLANCO ' ' + +/** + * Imprime una explicación de como usar el programa. + * + * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr). + */ void imprimir_uso(FILE* fh) { fprintf(fh, "\n"); fprintf(fh, "Modo de uso:\n"); @@ -30,166 +58,37 @@ void imprimir_uso(FILE* fh) { DEFAULT_F0); } -int argtod(const char* arg, Real* var, const char* nom) { - /* Puntero al último caracter bien interpretado por strtod. */ - char* err = NULL; - /* Realiza la conversión de un string a un Real */ - *var = strtod(arg, &err); - /* Si el caracter donde apunta endptr es 0 es porque se interpretó toda la - * cadena bien */ - if ((char)*err == '\0') { - return TRUE; - /* Si no, es que hubo error. */ - } else { - fprintf(stderr, "Error: El parámetro '%s' debe ser un número ", nom); - fprintf(stderr, "real. Usted ingresó '%s' pero '%s' no ", arg, err); - fprintf(stderr, "pudo ser interpretado.\n"); - return FALSE; - } -} - -int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) { - switch (argc) { - /* Si no tiene parámetros usa los valores por omisión. */ - case 1: - break; - /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un - * mensaje de error en caso de haberlo. */ - case 4: - /* Hay 3 parámetros, lee el 3er parámetro. */ - if (!argtod(argv[3], f0, "f0")) { - return FALSE; - } - /* Continúa con el resto de los parámetros. */ - case 3: - /* Hay al menos 2 parámetros, lee el 2do parámetro. */ - if (!argtod(argv[2], tf, "tf")) { - return FALSE; - } - /* Continúa con el resto de los parámetros. */ - case 2: - /* Hay al menos 1 parámetro, lee el 1er parámetro. */ - if (!argtod(argv[1], paso, "paso")) { - return FALSE; - } - break; /* Finaliza el switch (no lee más parámetros). */ - /* Hay demasiados parámetros, sale con mensaje de error. */ - default: - fprintf(stderr, "Error: Demasiados parámetros.\n"); - return FALSE; - } - /* TODO Verificar que el paso no sea cero y que tf > ti. */ - return TRUE; -} - -size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) { - /* Índice para iterar. */ - size_t i; - /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el - * tiempo final y el "tamaño" del paso. */ - size_t pasos = (size_t)((tf - ti) / paso); - /* Respeto la cantidad máxima de pasos admitida. */ - if (pasos > MAX_PASOS) { - pasos = MAX_PASOS; - } - /* Agrego el valor inicial de la función (para empezar a iterar). */ - (*res)[0] = f0; - /* Itero paso a paso calculando el valor de la función. */ - for (i = 1; i < pasos; i++) { - /* f(t+paso) = FUNCION(paso, f(t)) */ - (*res)[i] = FUNCION(paso, (*res)[i-1]); - } - return pasos; -} - -Real resultados_max(Resultados* res, size_t pasos) { - size_t i; - Real max = (*res)[0]; - for (i = 1; i < pasos; i++) { - if ((*res)[i] > max) { - max = (*res)[i]; - } - } - return max; -} - -Real resultados_min(Resultados* res, size_t pasos) { - size_t i; - Real min = (*res)[0]; - for (i = 1; i < pasos; i++) { - if ((*res)[i] < min) { - min = (*res)[i]; - } - } - return min; -} - -void inicializar_linea(char* linea, char caracter, size_t cant) { - size_t j; - for (j = 0; j < cant; j++) { - linea[j] = caracter; - } - linea[cant] = '\0'; -} - -void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) { - /* Máximo valor de la función. */ - Real min; - /* Mínimo valor de la función. */ - Real max; - /* Paso utilizado para la representación de las líneasMínimo valor de la función. */ - Real pasoh; - int i; - int j; - char linea[ANCHO]; - min = resultados_min(res, pasos); - max = resultados_max(res, pasos); - pasoh = (max - min) / (ALTO); - printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh); - /* Inicializa la línea. */ - inicializar_linea(linea, blanco, MAX_PASOS); - /* Por cada línea a dibujar. */ - for (i = ALTO; i >= 0; i--) { - /* Se fija si hay algún punto que entre en el rango. */ - for (j = 0; j < pasos; j++) { - /* Si está entre en el rango a imprimir, se agrega un punto. */ - if (((min + pasoh * i) <= (*res)[j]) - && ((*res)[j] < (min + pasoh * (i + 1)))) { - linea[j] = punto; - /* Si no, se lo deja en blanco. */ - } else { - linea[j] = blanco; - } - } - printf("%8.2f _%s\n", min + pasoh * i, linea); - } -} - +/** + * Programa principal. + * Este es el programa que se encarga de resolver el trabajo práctico. + * + * \param argc Cantidad de parámetros de línea de comandos ingresados. + * \param argv Parámetros de línea de comandos. + * + * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS. + */ int main(int argc, const char** argv) { - /* TODO: Declaración de variables. */ - Resultados resultados; - size_t pasos; - Real paso = DEFAULT_PASO; - Real tf = DEFAULT_TF; - Real f0 = DEFAULT_F0; - char punto = '*'; - char blanco = ' '; - + /* Declaración de variables. */ + Resultados resultados; /* Vector de resultados. */ + size_t pasos; /* Cantidad de pasos a dibujar. */ + Real paso = DEFAULT_PASO; /* Tamaño del paso */ + Real t0 = DEFAULT_T0; /* Tiempo inicial */ + Real tf = DEFAULT_TF; /* Tiempo final */ + Real f0 = DEFAULT_F0; /* Valor inicial de la función */ + char punto = DEFAULT_PUNTO; /* Caracter para dibujar un punto */ + char blanco = DEFAULT_BLANCO; /* Caracter para dibujar un blanco */ /* Obtención de datos. */ - if (!cargar_datos(argc, argv, &paso, &tf, &f0)) { + if (!cargar_datos(argc, argv, &paso, &t0, &tf, &f0)) { + /* Si hay error, imprime mensaje con modo de uso y sale con error. */ imprimir_uso(stderr); return EXIT_FAILURE; } - /* Cálculo de la solución, dejando en un array los valores de cada paso. */ - pasos = calcular(&resultados, paso, T0, tf, f0); - /* XXX - sacar o poner más lindo. */ - printf("paso = %f, tf = %f, f0 = %f, pasos = %i\n", paso, tf, f0, pasos); - - /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array - * y dibujando los resultados pertinentes. */ + pasos = resultados_calcular(&resultados, paso, t0, tf, f0); + /* Impresión de variables principales. */ + printf("\nt0 = %f | tf = %f | f0 = %f | paso = %f | pasos = %i\n\n", t0, tf, f0, paso, pasos); + /* Impresión del gráfico de la solución. */ resultados_graficar(&resultados, pasos, punto, blanco); - return EXIT_SUCCESS; }