
int string_to_number(int s) {
  int negative;
  int start_idx;
  int idx;
  int ch;
  int string_size;
  int int_val;
  int power;
  int is_integer;
  int done;
  int j;
  int real;
  int exponent;
  int non_digit_found;
  int non_real_char_found;
  int ret;

  is_string(s);

  ret = Mtrue;
  string_size = MstrSizeRef(s);
  if (string_size == 0) // empty string
    ret = Mfalse;
  else
  if (MgetChar(string_ref(s, 0)) == '-') {
    if (string_size == 1)
      ret = Mfalse;
    else {
      negative = 1;
      start_idx = 1;
    }
  }
  else {
    negative = 0;
    start_idx = 0;
  }

  if (ret == Mfalse) // not a number
    return ret;
  else {

    // determine if integer

    is_integer = 1;
    idx = string_size - 1;
    done = 0;
    non_digit_found = 0;
    non_real_char_found = 0;
    while (!done) {
      if (idx < start_idx)
        done = 1;
      else {
        ch = MgetChar(string_ref(s, idx));
        if (!isdigit(ch)) {
          non_digit_found = 1;
          is_integer = 0;
          if (!(ch == '.' || ch == 'e' || ch == '-' || ch == '+'))
            non_real_char_found = 1;
        }
        idx = idx - 1;
      }
    }

    if (is_integer) {
      if (non_digit_found)
        return Mfalse;
      else {
        power = 1;
        int_val = 0;
        for (idx = string_size - 1; idx >= start_idx; idx--) {
          ch = MgetChar(string_ref(s, idx));
          int_val = int_val + (ch - '0') * power;
          power = power * 10;
        }

        if (negative)
          int_val = - int_val;

        return make_integer(int_val);
      }
    }
    else { // real number
      ret = Mtrue;
      if (string_size == 1)
        ret = Mfalse;
      else
      if (non_real_char_found)
        ret = Mfalse;

      if (ret == Mfalse) // not a number
        return ret;
      else {
        // skip over leading zeros

        ch = MgetChar(string_ref(s, start_idx));
        while (ch == '0') {
          start_idx = start_idx + 1;
          ch = MgetChar(string_ref(s, start_idx));
        }

        real = make_vector_core(2 + PRECISION, REALSUBTYPE);
        done = 0;
        idx = start_idx;
        j = PRECISION + 2;
        exponent = 0;
        do {
          if (j == 2) {
            // skip insignificant digits if any
            ch = MgetChar(string_ref(s, idx));
            while ((idx < string_size) && isdigit(ch)) {
              idx = idx + 1;
              ch = MgetChar(string_ref(s, idx));
            }
            start_idx = idx + 1;
            done = 1;
          }
          else
          if (idx == string_size) 
            done = 1;
          else {
            ch = MgetChar(string_ref(s, idx));
            if (isdigit(ch)) {
              Mvecset(real, j, ch - '0');
              j = j - 1;
            }
            else
            if (ch == '.') { // TODO the mantissa doesn't have to have a '.'
                             // reals without a '.' fail now
              exponent = exponent + (idx - start_idx); 
            }
            else
            if (ch == 'e') {
              start_idx = idx + 1;
              done = 1;
            }
            idx = idx + 1;
          }
        } while (!done);
        if (negative)
          Mvecset(real, 1, 1);
        else
          Mvecset(real, 1, 0);
        // process exponent
        if (idx < string_size) {
          negative = 0; // now exponent sign
          ch = MgetChar(string_ref(s, start_idx));
          if (!isdigit(ch)) {
            if (ch == '-')
              negative = 1;
            start_idx = start_idx + 1;
          }
          power = 1;
          int_val = 0;
          for (idx = string_size - 1; idx >= start_idx; idx--) {
            ch = MgetChar(string_ref(s, idx));
            int_val = int_val + (ch - '0') * power;
            power = power * 10;
          }
          if (negative)
            int_val = -int_val;
          exponent = exponent + int_val;
        }
        Mvecset(real, 2, exponent);
//display_(real);
//writeln();
//my_exit(0);
        return real;
      }
    } // real number
  }
}

int number_to_string(int number) {
  int temp;
  int n;
  int n_temp;
  int negative;
  int s;
  int string_size;
  int string_idx;
  int first_idx;

  int exponent;
  int exponent_size;
  int negative_exponent;
  int idx;

  if (Mintegerp(number)) {
    n = get_integer_val(number);

    negative = n < 0;
    if (negative) {
      n = -n;
      string_size = 1;
    }
    else
      string_size = 0;

    // first get number of digits in n

    n_temp = n;
    do {
      string_size = string_size + 1;
      n_temp = n_temp / 10;
    } while (n_temp != 0);

    s = make_string(string_size);

    if (negative) {
      string_set(
        s,
        0,
        MmakeChar('-'));
      first_idx = 1;
    }
    else
      first_idx = 0;

    for (string_idx = string_size - 1; string_idx >= first_idx; string_idx--) {
      string_set( // set string in reverse order
        s,
        string_idx,
        MmakeChar(n % 10 + '0'));
      n = n / 10;
    }

    return s;
  }
  else
  if (Mrealp(number)) {
    if (Mvecref(number, 1) == 1) // negative real
      string_size = 1;
    else
      string_size = 0;
    string_size = string_size + 2; // 0.
    for (temp = PRECISION + 2; temp >= 3; temp--)
      string_size = string_size + 1;
    string_size = string_size + 1; // e
    exponent = Mvecref(number, 2);
    negative_exponent = exponent < 0;
    if (negative_exponent) {
      exponent = -exponent;
      string_size = string_size + 1;
    }

    // get number of digits in exponent

    n_temp = exponent;
    exponent_size = 0;
    do {
      exponent_size = exponent_size + 1;
      string_size = string_size + 1;
      n_temp = n_temp / 10;
    } while (n_temp != 0);

    // all the previous calculations just to get the string size

    s = make_string(string_size);

    string_idx = 0;
    if (Mvecref(number, 1) == 1) { // negative real
      string_set(
        s,
        string_idx,
        MmakeChar('-'));
      string_idx = string_idx + 1;
    }

    string_set(
      s,
      string_idx,
      MmakeChar('0'));
    string_idx = string_idx + 1;
    string_set(
      s,
      string_idx,
      MmakeChar('.'));
    string_idx = string_idx + 1;

    for (idx = PRECISION + 2; idx >= 3; idx--) {
      string_set(
        s,
        string_idx,
        MmakeChar(Mvecref(number, idx) + '0'));
      string_idx = string_idx + 1;
    }

    string_set(
      s,
      string_idx,
      MmakeChar('e'));
    string_idx = string_idx + 1;

    if (negative_exponent) {
      string_set(
        s,
        string_idx,
        MmakeChar('-'));
      string_idx = string_idx + 1;
    }

    for (string_idx = 0; string_idx >= - (exponent_size - 1); string_idx--) {
      string_set( // set string in reverse order
        s,
        string_idx + string_size - 1,
        MmakeChar(exponent % 10 + '0'));
      exponent = exponent / 10;
    }

    return s;
  }
  else {
    notnumber();
    return 0; // return not reached
  }
}
