In my FW for real-time embedded processor I need formatted print of decimal number. Standard printf/sprintf are not available in toolchain, so I need implement it myself.
I used naive approach of dividing by tens and taking remainder. But my target processor doesn't support division natively and software implementation take very long time (more than 200us) to compute. I wonder if there is quick way to fetch decimal digits from a number without division?
char* os_prn_decimal(char* outBuf, const char* end, uint32 v)
{
uint32 dgtIdx = 1000000000;
do
{
uint8 dgt = (uint8)(v / dgtIdx);
*outBuf = dgt + '0';
++outBuf;
v = v % dgtIdx;
dgtIdx /= 10;
} while (outBuf < end && dgtIdx > 0);
return outBuf;
}
A hint from daShier helped me to rectify my googling and I found this article https://forum.arduino.cc/index.php?topic=167414.0 that describes interesting approach to division by 10, which provides both quotient and modulo. Best part of it is complete lack of multiplications, divisions and cycles.
UPD: simulation measurement showed ~2X better performance of this solution compared to alternative solution and ~6X better performance over my original implementation.
void divmod10(uint32_t in, uint32_t &div, uint32_t &mod)
{
// q = in * 0.8;
uint32_t q = (in >> 1) + (in >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16); // not needed for 16 bit version
// q = q / 8; ==> q = in *0.1;
q = q >> 3;
// determine error
uint32_t r = in - ((q << 3) + (q << 1)); // r = in - q*10;
div = q + (r > 9);
if (r > 9) mod = r - 10;
else mod = r;
}