
// real number numeric functions

int make_real(int n) {
  int real;
  int src_mantissa;
  src_mantissa = get_mantissa(n);
  real = make_vector_core(2 + PRECISION, REALSUBTYPE);
  Mvecset(real, 1, get_sign(n));
  Mvecset(real, 2, get_exponent(n));
//for (i = 0; i < PRECISION; i++)
//  XMvecset(real, i + 3, Xget_digit(src_mantissa, i));
  memcpy32(
    cells, CELLADDRMASK(real) + 3,
    bigfloat_pool, src_mantissa,
    PRECISION);
  return real;
}

void get_real_val(int real, int n) {
  int dest_mantissa;
//display_(real); writeln();
  dest_mantissa = get_mantissa(n);
  set_sign(n, Mvecref(real, 1));
  set_exponent(n, Mvecref(real, 2));
//for (i = 3; i < PRECISION + 3; i++)
//  Xset_digit(dest_mantissa, i - 3, XMvecref(real, i));
  memcpy32(
    bigfloat_pool, dest_mantissa,
    cells, CELLADDRMASK(real) + 3,
    PRECISION);
  set_size(dest_mantissa, PRECISION - 1);
//print_bigfloat(n); writeln();
  return;
}

int realp(int x) {
  if (Mrealp(x))
    return Mtrue;
  else
  if (Mintegerp(x))
    return Mtrue;
  else
    return Mfalse;
}

int my_exact_to_inexact(int x) {
  int xType;

  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE) {
    init_bigfloat_from_integer(bigfloat_temp4, get_integer_val(x));
    return make_real(bigfloat_temp4);
  }
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, bigfloat_temp4);
    return make_real(bigfloat_temp4);
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}

int my_inexact_to_exact(int x) {
  int xType;

  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE)
    return make_integer(x);
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, bigfloat_temp4);
    return make_integer(bigfloat_to_int());
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}

int my_truncate(int x) {
  int xType;
 
  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE) {
    init_bigfloat_from_integer(bigfloat_temp4, get_integer_val(x));
    truncate_bigfloat(bigfloat_temp4, bigfloat_temp5);
    return make_real(bigfloat_temp5);
  }
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, bigfloat_temp4);
    truncate_bigfloat(bigfloat_temp4, bigfloat_temp5);
    return make_real(bigfloat_temp5);
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}

int my_floor(int x) {
  int xType;
 
  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE) {
    init_bigfloat_from_integer(floor_temp2, get_integer_val(x));
    floor_bigfloat(floor_temp2, floor_temp3);
    return make_real(floor_temp3);
  }
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, floor_temp2);
    floor_bigfloat(floor_temp2, floor_temp3);
    return make_real(floor_temp3);
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}

int my_ceiling(int x) {
  int xType;
 
  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE) {
    init_bigfloat_from_integer(ceiling_temp2, get_integer_val(x));
    ceiling_bigfloat(ceiling_temp2, ceiling_temp3);
    return make_real(ceiling_temp3);
  }
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, ceiling_temp2);
    ceiling_bigfloat(ceiling_temp2, ceiling_temp3);
    return make_real(ceiling_temp3);
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}

int my_round(int x) {
  int xType;
 
  isnumbervector(x);

  xType = MgetVecSubtype(x);
  if (xType == INTEGERSUBTYPE) {
    init_bigfloat_from_integer(round_temp2, get_integer_val(x));
    round_bigfloat(round_temp2, round_temp3);
    return make_real(round_temp3);
  }
  else
  if (xType == REALSUBTYPE) {
    get_real_val(x, round_temp2);
    round_bigfloat(round_temp2, round_temp3);
    return make_real(round_temp3);
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}
