Arbitrary precision (big number) library port for Arduino

Did some prototyping this evening (nothing on the telly) and prototyped two functions

Timings are uSec's

val = E / BigNumber(10); ==> 6912 uSec
E.div10(val); ==> 104..116 uSec; // diff values for diff nr's 50x faster

val E * 10; ==> 2268 uSec
E.mul10(val); ==> 120..136 uSec // 15x faster

// code experimental, based upon that the internal data is BASE 10,
// so a divide / multiply by 10 is done by manipulating the place of the decimal point.
// testing has just begon...

add to BigNumber.h

  void mul10 (BigNumber & product) const;
  void div10 (BigNumber & quotient) const;

add to BigNumber.cpp

void BigNumber::mul10(BigNumber & product) const
{
  bc_multiply10 (num_, &product.num_, scale_);
}

void BigNumber::div10(BigNumber & quotient) const
{
  bc_divide10 (num_, &quotient.num_, scale_);
}

add to number.h

_PROTOTYPE(void bc_multiply10, (bc_num n1, bc_num *prod, int scale));
_PROTOTYPE(int bc_divide10, (bc_num n1, bc_num *quot, int scale));

add to number.c

int
bc_divide10 (n1, quot, scale)
     bc_num n1, *quot;
     int scale;
{
  bc_num qval;
  if (n1->n_len == 1)  // must keep 1 digit before decimal point
  {
    qval = bc_new_num (n1->n_len, n1->n_scale);
    qval->n_sign = n1->n_sign;
    memset (&qval->n_value[qval->n_len], 0, scale);
    memcpy (qval->n_value+1, n1->n_value, qval->n_len + MIN(qval->n_scale, scale));  // note +1  , leading zero
  }
  else
  {
    qval = bc_new_num (n1->n_len-1, n1->n_scale+1);  // adjust decimal point
    qval->n_sign = n1->n_sign;
    memset (&qval->n_value[qval->n_len], 0, scale);
    memcpy (qval->n_value, n1->n_value, qval->n_len + MIN(qval->n_scale, scale));
  }

  bc_free_num (quot);
  *quot = qval;
  return 0;	
}

void
bc_multiply10 (n1, prod, scale)
     bc_num n1, *prod;
     int scale;
{
  bc_num pval;
  
  if (bc_compare(n1, _one_) == 1)  // n1 > 1 ?
  {
    pval = bc_new_num (n1->n_len+1, n1->n_scale-1);  // move decimal point
    pval->n_sign = n1->n_sign;
    memset (&pval->n_value[n1->n_len], 0, scale);
    memcpy (pval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale, scale));
  }
  else //   this branch is not tested yet
  {
    pval = bc_new_num (n1->n_len, n1->n_scale);
    pval->n_sign = n1->n_sign;
    memset (&pval->n_value[n1->n_len], 0, scale);
    memcpy (pval->n_value, n1->n_value+1, n1->n_len + MIN(n1->n_scale, scale));
  }
  bc_free_num (prod);
  
  *prod = pval;
}

Mod10() was a bridge too far for tonight :slight_smile: