/* Ofront+ 1.0 -sC -48 */
#include "SYSTEM.oh"




export void Reals_Convert (SHORTREAL x, SHORTINT n, CHAR *d, INTEGER d__len);
export void Reals_ConvertH (SHORTREAL y, CHAR *d, INTEGER d__len);
export void Reals_ConvertHL (REAL x, CHAR *d, INTEGER d__len);
export SHORTINT Reals_Expo (SHORTREAL x);
export SHORTINT Reals_ExpoL (REAL x);
export void Reals_RealToStr (REAL x, INTEGER digits, CHAR *d, INTEGER d__len);
export void Reals_SetExpo (SHORTINT e, SHORTREAL *x);
export void Reals_SetExpoL (SHORTINT e, REAL *x);
export SHORTREAL Reals_Ten (SHORTINT e);
export REAL Reals_TenL (SHORTINT n);
static void Reals_Unpack (BYTE *b, INTEGER b__len, BYTE *d, INTEGER d__len);

#include <stdio.h>
#define Reals_Offset(adr, offset)  ((SYSTEM_ADRINT)adr + offset)
#define Reals_sprintd(buf, format, x)  sprintf ((char*)buf, (char*)format, x)
#define Reals_sprintf(buf, format, x)  sprintf ((char*)buf, (char*)format, x)

/*============================================================================*/

SHORTREAL Reals_Ten (SHORTINT e)
{
  REAL r, power;
  r = (REAL)1;
  power = (REAL)10;
  while ((INTEGER)e > 0) {
    if (__ODD(e)) {
      r = r * power;
    }
    power = power * power;
    e = (SHORTINT)__ASHR((INTEGER)e, 1, INTEGER);
  }
  return (SHORTREAL)r;
}

/*----------------------------------------------------------------------------*/
REAL Reals_TenL (SHORTINT n)
{
  REAL r, power;
  r = (REAL)1;
  power = (REAL)10;
  while ((INTEGER)n > 0) {
    if (__ODD(n)) {
      r = r * power;
    }
    power = power * power;
    n = (SHORTINT)__ASHR((INTEGER)n, 1, INTEGER);
  }
  return r;
}

/*----------------------------------------------------------------------------*/
SHORTINT Reals_Expo (SHORTREAL x)
{
  return (SHORTINT)__MASK(__ASHR(__VAL(INTEGER, x), 23, INTEGER), -256);
}

/*----------------------------------------------------------------------------*/
SHORTINT Reals_ExpoL (REAL x)
{
  INTEGER exp, offset;
  x = __ABS(x);
  exp = (INTEGER)__ASHR(__VAL(LONGINT, x), 52, LONGINT);
  offset = 1023;
  while (exp == 0) {
    x = x + x;
    exp = (INTEGER)__ASHR(__VAL(LONGINT, x), 52, LONGINT);
    offset += 1;
  }
  return (SHORTINT)(exp - offset);
}

/*----------------------------------------------------------------------------*/
void Reals_SetExpo (SHORTINT e, SHORTREAL *x)
{
  *x = __VALSR((INTEGER)((__VAL(SET, *x) & ~0x01fe) | (SET)__ASHL((INTEGER)e, 23, INTEGER)));
}

/*----------------------------------------------------------------------------*/
void Reals_SetExpoL (SHORTINT e, REAL *x)
{
  SET h;
  __GET((SYSTEM_ADRINT)x + 4, h, SET);
  h = (h & ~0x0ffe) | (SET)__ASHL((INTEGER)e, 20, INTEGER);
  __PUT((SYSTEM_ADRINT)x + 4, h, SET);
}

/*----------------------------------------------------------------------------*/
void Reals_Convert (SHORTREAL x, SHORTINT n, CHAR *d, INTEGER d__len)
{
  INTEGER i, k;
  i = (INTEGER)__ENTIER(x);
  k = 0;
  while (k < (INTEGER)n) {
    d[__X(k, d__len, (CHAR*)"Reals", 20007)] = (CHAR)(__MOD(i, 10) + 48);
    i = __DIV(i, 10);
    k += 1;
  }
}

/*----------------------------------------------------------------------------*/
static void Reals_Unpack (BYTE *b, INTEGER b__len, BYTE *d, INTEGER d__len)
{
  BYTE i, k;
  INTEGER len;
  i = 0;
  len = b__len;
  while ((INTEGER)i < len) {
    k = (BYTE)__ASHR((INTEGER)((CHAR)b[__X(i, b__len, (CHAR*)"Reals", 22070)]), 4, INTEGER);
    if ((INTEGER)k > 9) {
      d[__X(__ASHL((INTEGER)i, 1, INTEGER), d__len, (CHAR*)"Reals", 22322)] = (BYTE)((INTEGER)k + 55);
    } else {
      d[__X(__ASHL((INTEGER)i, 1, INTEGER), d__len, (CHAR*)"Reals", 22358)] = (BYTE)((INTEGER)k + 48);
    }
    k = (BYTE)__MASK((INTEGER)((CHAR)b[__X(i, b__len, (CHAR*)"Reals", 22582)]), -16);
    if ((INTEGER)k > 9) {
      d[__X(__ASHL((INTEGER)i, 1, INTEGER) + 1, d__len, (CHAR*)"Reals", 22836)] = (BYTE)((INTEGER)k + 55);
    } else {
      d[__X(__ASHL((INTEGER)i, 1, INTEGER) + 1, d__len, (CHAR*)"Reals", 22874)] = (BYTE)((INTEGER)k + 48);
    }
    i += 1;
  }
}

void Reals_ConvertH (SHORTREAL y, CHAR *d, INTEGER d__len)
{
  Reals_Unpack((void*)(SYSTEM_ADRINT)&y, 4, (void*)(SYSTEM_ADRINT)d, d__len);
}

/*----------------------------------------------------------------------------*/
void Reals_ConvertHL (REAL x, CHAR *d, INTEGER d__len)
{
  Reals_Unpack((void*)(SYSTEM_ADRINT)&x, 8, (void*)(SYSTEM_ADRINT)d, d__len);
}

/*----------------------------------------------------------------------------*/
void Reals_RealToStr (REAL x, INTEGER digits, CHAR *d, INTEGER d__len)
{
  CHAR buf[28];
  CHAR format[8];
  format[0] = '%';
  format[1] = '.';
  __ASSERT(0 < digits && digits <= 17, 0, (CHAR*)"Reals", 28713);
  __ASSERT(Reals_sprintd((SYSTEM_ADRINT)format + 2, (SYSTEM_ADRINT)(CHAR*)"%dG", digits) < 6, 0, (CHAR*)"Reals", 29002);
  __ASSERT(Reals_sprintf((SYSTEM_ADRINT)buf, (SYSTEM_ADRINT)format, x) < 28, 0, (CHAR*)"Reals", 29244);
  __STRCOPYCC(buf, d, __MIN(d__len, 28), (CHAR*)"Reals", 29695);
}

/*----------------------------------------------------------------------------*/

export void *Reals__init (void)
{
  __DEFMOD;
  __REGMOD("Reals", 0);
/* BEGIN */
  __ENDMOD;
}
