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_, "ient.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