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 );
}
Si considera que el truco a [b] es una trampa (ya que es realmente un complemento), entonces esto funciona en su lugar. Pero las búsquedas de tablas también incluyen punteros añadidos.
Ver http://en.wikipedia.org/wiki/IBM_1620 , una computadora que realmente hizo la suma usando tablas de búsqueda ...
Algo satisfactorio sobre el uso de un mecanismo de tabla para 'acelerar' una operación que en realidad podría hacerse en una sola instrucción.
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;
}