juegos

Juegos de terminal de Pancho: Catan (TUI, GUI, web, servidor, PicoCalc), ajedrez, calculadora y minijuegos
git clone https://git.lu3dhn.xyz/juegos.git
Log | Files | Refs

dec.h (2593B)


      1 /* dec.h - numeros decimales de punto flotante en base 10 (como una calculadora):
      2  * mantisa de 18 digitos (15 que se muestran + 3 de guarda) y exponente.
      3  * Sin float, sin malloc, sin stdio: corre igual en Linux y en el RP2040. */
      4 #ifndef DEC_H
      5 #define DEC_H
      6 #include <stdint.h>
      7 #include <stdbool.h>
      8 
      9 #define DEC_DIGITS 18
     10 #define DEC_EMAX   99                 /* |x| < 10^100, como la Casio */
     11 
     12 enum { DE_OK, DE_MATH };              /* err: fuera de rango, division por cero, dominio */
     13 
     14 /* valor = m * 10^(e-17), con 10^17 <= m < 10^18 (m = 0 para el cero);
     15  * e es el exponente del primer digito (notacion cientifica). */
     16 typedef struct { uint64_t m; int16_t e; uint8_t neg, err; } Dec;
     17 
     18 extern const Dec DEC_ZERO, DEC_ONE;
     19 
     20 Dec  dec_int(int64_t v);
     21 Dec  dec_err(void);
     22 /* Lee "123.45", "-1.5E-7", ".5", "2e3"; *end queda en el primer caracter no usado
     23  * (NULL si no hay numero). */
     24 Dec  dec_parse(const char *s, const char **end);
     25 
     26 Dec  dec_add(Dec a, Dec b);
     27 Dec  dec_sub(Dec a, Dec b);
     28 Dec  dec_mul(Dec a, Dec b);
     29 Dec  dec_div(Dec a, Dec b);
     30 Dec  dec_neg(Dec a);
     31 Dec  dec_abs(Dec a);
     32 Dec  dec_sqrt(Dec a);
     33 Dec  dec_mul_int(Dec a, int64_t k);
     34 Dec  dec_div_int(Dec a, int64_t k);
     35 Dec  dec_pow_int(Dec a, int64_t n);   /* exacta mientras entre en 18 digitos */
     36 Dec  dec_scale10(Dec a, int k);       /* a * 10^k */
     37 
     38 int  dec_cmp(Dec a, Dec b);           /* -1, 0, 1 */
     39 int  dec_cmp_abs(Dec a, Dec b);
     40 static inline bool dec_is_zero(Dec a) { return a.m == 0 && !a.err; }
     41 static inline bool dec_bad(Dec a) { return a.err != DE_OK; }
     42 bool dec_is_int(Dec a);
     43 bool dec_to_int(Dec a, int64_t *out); /* falso si no es entero o no entra */
     44 
     45 Dec  dec_trunc(Dec a);                /* hacia cero */
     46 Dec  dec_floor(Dec a);
     47 Dec  dec_round_int(Dec a);            /* al entero mas cercano (mitad: lejos de cero) */
     48 Dec  dec_fmod(Dec a, Dec b);          /* a - trunc(a/b)*b, exacto si a y b son "decimales cortos" */
     49 Dec  dec_round_sig(Dec a, int n);     /* a n digitos significativos, mitad lejos de cero */
     50 Dec  dec_round_dec(Dec a, int n);     /* a n decimales (Fix), mitad lejos de cero */
     51 /* Pega a cero o a +-1 lo que esta a menos de 'tol' digitos (resultados de trig). */
     52 Dec  dec_snap(Dec a, int tol);
     53 
     54 /* Digitos de la mantisa (18, '0'..'9', sin terminar en 0 si se pide) y exponente. */
     55 void dec_digits(Dec a, char d[DEC_DIGITS + 1]);
     56 
     57 /* int64 a texto (str_int usa long, que en la Pico es de 32 bits) */
     58 int  i64_text(char *buf, int n, int pos, int64_t v);
     59 
     60 /* Texto simple para depuracion y para guardar: "-1.2345E-7" (round-trip exacto). */
     61 int  dec_to_text(Dec a, char *buf, int n);
     62 
     63 #endif