#ifndef __MFASTFPU

#define __MFASTFPU

//#define MFPU_USAR_TABLA_FTOL

#ifdef  MFPU_USAR_TABLA_FTOL
  extern const unsigned g_GEFTolTABLE  [256];
#endif  //MFPU_USAR_TABLA_FTOL

extern const double   g_MEdHalf;
extern const double   g_MEdHalfplusEpsilon;



#define MFPU_ALLMANTISA_MASK ((unsigned)(1<<24)-1)
#define MFPU_EXPONENT(n)     ((n>>23)&0xff)

#define MFPU_USEASINT(f)          (*((int *)&(f)))
#define MFPU_MANTISA(n)           ( (n|0x0800000) )
#define MFPU__EXPmayor149(n,c)    ((n)>149?0:(c))
#define MFPU__EXPmenor127(n,c)    ((n)<127?MFPU_ALLMANTISA_MASK:(c))
#define MFPU__EXPentre127y149(n)  ( (1<<(150-(n)))-1)
#define MFPU_MASCARA_EXPONENTE(n) ( MFPU__EXPmayor149(n,MFPU__EXPmenor127(n,MFPU__EXPentre127y149(n))) ) 


#define MFPU_TEST_MANTISA_CON_TABLA(n)    \
  ( MFPU_MANTISA(n) & g_GEFTolTABLE[MFPU_EXPONENT(n)] )

#define MFPU_TEST_MANTISA_SIN_TABLA(n)      \
  ( MFPU_MANTISA(n) & MFPU_MASCARA_EXPONENTE(MFPU_EXPONENT(n)) )


#ifdef  MFPU_USAR_TABLA_FTOL
  #define MFPU_TEST_MANTISA   MFPU_TEST_MANTISA_CON_TABLA
#else
  #define MFPU_TEST_MANTISA   MFPU_TEST_MANTISA_SIN_TABLA
#endif  //MFPU_USAR_TABLA_FTOL

inline int MFPU_Floor(const float f)
{
  int i[2];

  __asm fld f
  if( MFPU_USEASINT(f)&(((unsigned)1<<31)-1) && MFPU_TEST_MANTISA(MFPU_USEASINT(f)) )
    if( MFPU_USEASINT(f)>0 )
      __asm fsub  g_MEdHalf
    else
      __asm fsub  g_MEdHalfplusEpsilon

  __asm   fistp   qword ptr i;
  return(i[0]);
}

inline int MFPU_Ceil(const float f)
{
  int i[2];

  __asm fld f
  if( MFPU_TEST_MANTISA(MFPU_USEASINT(f)) )
    if( MFPU_USEASINT(f)>0 )
      __asm fadd  g_MEdHalfplusEpsilon
    else
      __asm fadd  g_MEdHalf

  __asm   fistp   qword ptr i;
  return(i[0]);
}



inline int MFPU_ftolFast(const float f)
{
  int i[2];
  __asm   fld f
  __asm   fistp   qword ptr i;
  return(i[0]);
}

inline int MFPU_ftol(const float f)
{
  int i[2];
  __asm fld f
  if( MFPU_TEST_MANTISA(MFPU_USEASINT(f)) )
  {
    if( MFPU_USEASINT(f)>0 )
      __asm fsub  g_MEdHalf
    else
      __asm fadd  g_MEdHalf 
  }
  __asm   fistp   qword ptr i;
  return(i[0]);
}

inline float MFPU_ltof(const int l)
{
  float f;
  __asm fild   l
  __asm fstp   f;
  return(f);
}


inline float MFPU_fceil(const float f)
{
  return(float(MFPU_Ceil(f)));
}

inline float MFPU_floor(const float f)
{
  return(float(MFPU_Floor(f)));
}



#endif