[ create a new paste ] login | about

Link: http://codepad.org/7OZhuiT1    [ raw code | fork ]

C, pasted on Sep 20:
/* stores a bignum as a ASCII string in a base 10 */

static mp_digit my_divide_by = 1;
static int digits_at_a_time = 0;
static const char s_10map[] = "0123456789";

static void init_mp_tobase10(void) {
   if( digits_at_a_time ) return;
   while(1) {
      mp_digit test = my_divide_by * 10;
      if( test >= MP_DIGIT_MAX ) break;
      if( test < my_divide_by ) break; /* test for overflow, too */
      ++digits_at_a_time;
      my_divide_by = test;
   }
}

int
mp_tobase10 (mp_int * a, char *str)
{
  int     res, digit, digs;
  mp_int  t;
  mp_digit d, prev;
  char   *_s = str;

  /* quick out if its zero */
  if (mp_iszero(a) == 1) {
     *str++ = '0';
     *str = '\0';
     return MP_OKAY;
  }
  

  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
    return res;
  }

  if (t.sign == MP_NEG) {
    ++_s;
    *str++ = '-';
    t.sign = MP_ZPOS;
  }

  init_mp_tobase10();
  digs = 0;

  if ((res = mp_div_d (&t, my_divide_by, &t, &prev)) != MP_OKAY) {
    mp_clear (&t);
    return res;
  }

  while (mp_iszero (&t) == 0) {
    if ((res = mp_div_d (&t, my_divide_by, &t, &d)) != MP_OKAY) {
      mp_clear (&t);
      return res;
    }
    for( digit = digits_at_a_time-1; digit > 0; --digit ) {
      *(str++) = s_10map[ prev % 10 ];
      prev = prev / 10;
    }
    *(str++) = s_10map[ prev ];
    prev = d;
    digs += digits_at_a_time;
  }

  while( prev != 0 ) {
    *(str++) = s_10map[ prev % 10 ];
    prev = prev / 10;
    digs++;
  }

  bn_reverse ((unsigned char *)_s, digs);

  mp_clear (&t);
  return MP_OKAY;
}


Create a new paste based on this one


Comments: