/*
  FP8_E3M4 playground - s.eee.mmmm (bias 3)
  Value = (-1)^s*(1+mmmm/16)*2^(eee-3)

  Special cases:
    eee==000 - unnormalized mantissa == (0+0.mmmm)
    0.000.0000 == 0
    s.111.0000 == +/-inf (signed infinity)
    s.111.1xxx == nan (not a number)

  Ranges of values :
    0.000.0001 - smallest unnormalized: (0+1/16)*2^(1-3) == 0.015625  [1/16/4]
    0.000.1111 - largest unnormalized:  (0+15/16)*2^(1-3) == 0.234375 [15/16/4]

    0.001.0000 - smallest normalized:   (1+0/16)*2^(1-3) == 0.25      [16/16/4]
    0.110.1111 - largest normalized:    (1+15/16)*2^(6-3) == 15.5     [31/16*8]

  Compiling:
    gcc -std=c99 -Wall -Wpedantic -lm -o proov main.c fp8_e3m4_ops.c fp8_e3m4.c

  For debugging, add -DDEBUGGING like here:
    gcc -std=c99 -DDEBUGGING -Wall -Wpedantic ...

  ------------------------------------------------------------------------
  (C) 2026 Peeter Ellervee <peeter.ellervee@taltech.ee>
*/

#include <stdio.h>

#include "fp8_e3m4.h"


/*
 * Just testing...
 */
int main(void) {

  const fp8_e3m4 num[8] = {
    /* 0.015625 */  0x01,  /* -0.234375 */  0x8f,
    /* 0.250000 */  0x10,  /* -0.265625 */  0x91,
    /* 15.500000 */ 0x6f,  /* -15.000000 */ 0xee,
    /* -inf */      0x70,  /* nan */        0x7c
  };
  float val_l,val_r;
  fp8_e3m4 num_l,num_r,num_a,num_s,num_m,num_d;
  fp8_e3m4_str op_l,op_r;

  printf("Example numbers:\n");
  for (int i=0; i<8; i++) {
    fp8_e3m4_unpack(num[i],&op_l);
    val_l=fp8_to_float(num[i]);
    printf("%02X : %10f %2d %2d %3x : %02x\n",num[i],val_l,
	   op_l.sign,op_l.exp,op_l.mant,float_to_fp8(val_l));
  }

  printf("\nEnter two floats (space separated, CTRL-C stops):\n");
  while (1) {
    scanf("%f %f",&val_l,&val_r);

    num_l=float_to_fp8(val_l);
    fp8_e3m4_unpack(num_l,&op_l);
    num_r=float_to_fp8(val_r);
    fp8_e3m4_unpack(num_r,&op_r);

    printf("1st: %f : %02x : %2d %2d %3x : %f\n",
	   val_l,num_l,op_l.sign,op_l.exp,op_l.mant,fp8_to_float(num_l));
    printf("2nd: %f : %02x : %2d %2d %3x : %f\n",
	   val_r,num_r,op_r.sign,op_r.exp,op_r.mant,fp8_to_float(num_r));

    num_a=fp8_e3m4_add(num_l,num_r);
    num_s=fp8_e3m4_sub(num_l,num_r);
    num_m=fp8_e3m4_mul(num_l,num_r);
    num_d=fp8_e3m4_div(num_l,num_r);
    printf("add: %02x : %8f\nsub: %02x : %8f\n",
	   num_a,fp8_to_float(num_a),num_s,fp8_to_float(num_s));
    printf("mul: %02x : %8f\ndiv: %02x : %8f\n",
	   num_m,fp8_to_float(num_m),num_d,fp8_to_float(num_d));

  }
  return 0;
}
