unsigned add( unsigned a, unsigned b )
{
return (unsigned)&((char*)a)[b]; // ignore compiler warnings
// (if pointers are bigger than unsigned). it still works.
}
unsigned umul( unsigned a, unsigned b )
{
unsigned res = 0;
while( a != 0 ){
if( a & 1) res = add( res, b );
b <<= 1;
a >>= 1;
}
return res;
}
int mul( int a, int b ){
return (int)umul( (unsigned)a, (unsigned)b );
}
Se você considera o truque a [b] uma trapaça (já que é realmente um complemento), isso funciona. Mas as pesquisas de tabela também envolvem acréscimos de ponteiro.
Veja http://en.wikipedia.org/wiki/IBM_1620 - um computador que realmente fez adição usando tabelas de pesquisa ...
Algo satisfatório sobre o uso de um mecanismo de tabela para 'acelerar' uma operação que poderia realmente ser realizada em uma instrução.
static unsigned sumtab[17][16]= {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16},
{ 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17},
{ 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18},
{ 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19},
{ 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20},
{ 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21},
{ 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22},
{ 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23},
{ 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24},
{10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
{11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26},
{12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27},
{13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28},
{14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29},
{15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30},
{16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}
};
unsigned add( unsigned a, unsigned b )
{
static const int add4hack[8] = {4,8,12,16,20,24,28,32};
unsigned carry = 0;
unsigned (*sumtab0)[16] = &sumtab[0];
unsigned (*sumtab1)[16] = &sumtab[1];
unsigned result = 0;
int nshift = 0;
while( (a|b) != 0 ){
unsigned psum = (carry?sumtab1:sumtab0)[ a & 0xF ][ b & 0xF ];
result = result | ((psum & 0xF)<<nshift);
carry = psum >> 4;
a = a >> 4
b = b >> 4;
nshift= add4hack[nshift>>2]; // add 4 to nshift.
}
return result;
}