// Módulo de fracciones. Es un tipo opaco: quien lo usa solo tiene punteros.
// Una fracción siempre está reducida y su denominador siempre es positivo.
// Todas las funciones exigen que los productos y las sumas de la cuenta quepan en un int.
#ifndef FRACTION_H
#define FRACTION_H

typedef struct fraction Fraction;

// Crea la fracción numerator / denominator, ya reducida: 2 / -4 queda como -1 / 2, y 0 / 5
// queda como 0 / 1. Devuelve NULL si denominator es 0 o si no hay memoria.
// Owner: quien llama, que debe liberarla con fraction_free.
Fraction *fraction_new(int numerator, int denominator);

// Libera la fracción. Acepta NULL.
void fraction_free(Fraction *fraction);

// Devuelven el numerador y el denominador de la forma reducida.
int fraction_numerator(const Fraction *fraction);
int fraction_denominator(const Fraction *fraction);

// Devuelven una fracción nueva con el resultado, o NULL si no hay memoria. No cambian a ni b.
// Owner del resultado: quien llama.
Fraction *fraction_add(const Fraction *a, const Fraction *b);
Fraction *fraction_multiply(const Fraction *a, const Fraction *b);

// Devuelve 1 si valen lo mismo y 0 si no.
int fraction_equal(const Fraction *a, const Fraction *b);

// Escribe la fracción en la forma 3/4, sin salto de línea. Si el denominador es 1, escribe
// solo el numerador: 2, no 2/1.
void fraction_print(const Fraction *fraction);

#endif
