proof of concept... хотя, боюсь, тут не поймут.
//#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
typedef unsigned char uint_fast8_t; // pic18
#define BCD_ORDER 26 // log2(10^8)
#define BCD_MAX_DIGITS 8 // sizeof(bcd_t)*2
typedef unsigned long bcd_t;
// этот кусок можно переписать с использованием команд CPU
// предназначенных для работы с двоично-десятичными числами -- на порядок быстрее.
inline static bcd_t bcd_add(bcd_t a, bcd_t b)
{
bcd_t c;
a = a + 0x06666666; // the magic number of the beast!
c = a + b;
b = a ^ b;
a = c ^ b;
a = ~a & 0x11111110;
b = (a >> 2) | (a >> 3);
return c - b;
}
char *ulong2str(char *retval, unsigned long val)
{
static char buf[BCD_MAX_DIGITS+1];
char *p;
uint_fast8_t n;
unsigned long m=1;
bcd_t t=1, r=0;
n=BCD_ORDER;
do {
if (val&m) r=bcd_add(r, t);
t=bcd_add(t, t);
//fprintf(stderr, "t=%lx, r=%lx\n", t, r);
m<<=1;
} while(--n);
if (retval==NULL) retval=buf;
p=retval, n=BCD_MAX_DIGITS;
do {
*p++=(r>>(BCD_MAX_DIGITS*4-4))+'0';
r<<=4;
} while (--n);
*p=0;
p=retval;
while (p[0]=='0' && p[1]) p++;
return p;
}
int main()
{
char *s;
asm("nop");
s=ulong2str(NULL, 12345678);
asm("nop");
puts(s);
return 0;
}
[ZX]