TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: RedPic en 09 de Febrero de 2010, 05:06:26

Título: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 05:06:26
Pues la pregunta es exactamente esa ... ¿Como estáis de aritmética de mas de 32 bits?

Me explico: De un dispositivo recojo exactamente 40 bits que representan un único número decimal equivalente. La cosa es que nunca he trabajado con mas de 32 bits y no se cómo componer un decimal de con 32+8 bits ¿En dos variables de 32 bits? ¿En una de 32 y otra de 8 y después ... ? ¿Qué?

O sea si recojo 1111111111111111111111111111111111111111 (40 "unos") tengo que generar el decimal 1.099.511.627.775 en mi super printf("%XLu") Pongo %XLu porque es un entero de tamaño XL (como las camisetas (sudaderas, remeras) para gente amplia como yo)  :mrgreen:

Se aceptan sugerencias, ideas, conceptos y saltos jabonados de delfin.  :shock:
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: Nocturno en 09 de Febrero de 2010, 05:12:14
¿Qué necesitas hacer con ese chorizo?, ¿sólo almacenarlo e imprimirlo, o también operaciones matemáticas?
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 05:34:53
¿Qué necesitas hacer con ese chorizo?, ¿sólo almacenarlo e imprimirlo, o también operaciones matemáticas?

Leo los 40 bits binarios, los convierto a decimal y transmito, uno a uno, los dígitos en ASCII del decimal (0x31,0x30,0x39,0x39 ... del decimal del ejemplo anterior 1099.... )

Ni sumo , ni resto, mi multiplico ni mucho menos divido.  :D

Por cierto ... ¿ sabéis algún chiste matemático, biológico y teológico ? ...

Dicen que Dios en el momento del Génesis proclamó - Creced y multiplicaos.
Y dijeron las tozudas amebas (http://es.wikipedia.org/wiki/Ameba) - Pues nosotras nos dividiremos.
A lo que Dios respondió - Creced y multiplicaos ... por división.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 07:11:57
Sus pongo un ejemplo real de lo que estoy enfrentando.

Recibo 40 bits : 0000000100001000010100110111100000111111
Este número binario es en decimal : 0004434655295

Pero como mi aritmética no pasa de los 32 Bits divido los 40 que recibo en dos bloques de 8 + 32 bits así que ...

Recibo 8+32 bits : 00000001     00001000010100110111100000111111
Estos números binarios son en decimal : 1 + 139687999

Y cuadran porque 1 * 2^32 + 139687999 es exactamente lo que necesito que es el 0004434655295

El problema es ... ¿como cogno genero ese 1 * 2^32? que obviamente es un número de mas de 32 bits  :shock: :shock:

Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 07:22:58
Y los dobles saltos mortales carpados hacia delante (también conocidos como Sukaharas) ...

Esos 40 bits pueden ser troceados de cualquier forma u manera, siempre y cuando se obtenga el valor de un dígito según su "peso" en la cifra ...

Quizir:

Si mis anteriores 40 bits los divido en 32+8 (en lugar de los 8+32) obtengo también el mismo resultado decimal

Si proceso 32+8 :  00000001000010000101001101111000   00111111
estos son en decimal 17322872 y 63

Y también cuadran perfectamente, pero esta vez como 17322872 * 2^8 + 63

Pero estamos en las mismas ya que 17322872 * 2^8 es también un número de mas de 32 bits.

 :5] :5] :5]
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: erdanieee en 09 de Febrero de 2010, 07:59:48
Buenas RedPic,

si no necesitas hacer operaciones aritméticas se me ocurre la siguiente manera:
  - coges el primer bloque de 4 bits (del 0 al 3), lo conviertes a decimal (tendría 2 dígitos: x2, x1). Ej: 0xf -> 15 -> x2=1, x1=5
  - coges el segundo bloque (4-7) lo conviertes a decimal igual que antes (sean y2, y1 los dos dígitos en decimal)
  - así obtienes 2 dígitos decimales de tu conversión final, que son d1=x1, d2=primerDígito(x2+y1). Si el resultado de x2+y1 es mayor de 9 sumas uno al segundo dígito del segundo bloque (y2++).
  - repites el bucle para los siguientes bloques: bloque (4-7), que ya lo tienes convertido a decimal y modificado (si te llevabas una :-)) y bloque (8-11). En el último ciclo obtienes 3 dígitos en lugar de 2...


Probablemente haya una forma más sencilla de hacerlo directamente en binario, sin tener que convertir cada bloque a decimal, pero así a vista de pájaro no se me ocurre como.

saludos!!
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 08:12:59
Gracias, erdanieee, voy a ver si logro entenderte (soy muy bruto y hay veces que me cuesta encontrarme la espalda) ... y ya te digo algo. Gracias, de nuevo.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: erdanieee en 09 de Febrero de 2010, 08:18:21
no te molestes, acabo de ver que está mal lo que te he dicho! jajaja, qué desastre!
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: J1M en 09 de Febrero de 2010, 08:53:15
Diego a ver si esto te sirve:
http://www.ccsinfo.com/forum/viewtopic.php?t=28816&view=next

Lo que hace el artista de telmah es crear una variable de 64bits; Además de regalo van varias funciones de operaciones aritméticas...!

Código: [Seleccionar]
union bits64 {
   int8 b[8];
   int32 w[2];
};
typedef union bits64 int64;
int64 scratch64;
int1 BORROW=FALSE;
#bit CARRY=0xFD8.0

//Macro to add two 64bit values. Result into the first
#define M_add64x64(M_a,M_b) \
   #asm\
   movf M_b.b[0],0\
   addwf M_a.b[0],1\
   movf M_b.b[1],0\
   addwfc M_a.b[1],1\
   movf M_b.b[2],0\
   addwfc M_a.b[2],1\
   movf M_b.b[3],0\
   addwfc M_a.b[3],1\
   movf M_b.b[4],0\
   addwfc M_a.b[4],1\
   movf M_b.b[5],0\
   addwfc M_a.b[5],1\
   movf M_b.b[6],0\
   addwfc M_a.b[6],1\
   movf M_b.b[7],0\
   addwfc M_a.b[7],1\
   #endasm
//Macro as above, to subtract two 64bit values.
#define M_sub64x64(M_a,M_b) \
   #asm\
   movf M_b.b[0],0\
   subwf M_a.b[0],1\
   movf M_b.b[1],0\
   subwfb M_a.b[1],1\
   movf M_b.b[2],0\
   subwfb M_a.b[2],1\
   movf M_b.b[3],0\
   subwfb M_a.b[3],1\
   movf M_b.b[4],0\
   subwfb M_a.b[4],1\
   movf M_b.b[5],0\
   subwfb M_a.b[5],1\
   movf M_b.b[6],0\
   subwfb M_a.b[6],1\
   movf M_b.b[7],0\
   subwfb M_a.b[7],1\
   #endasm

//Macros to shift a 64bit value
#define M_shiftleft64(x) shift_left(&x,8,0)
#define M_shiftright64(x) shift_right(&x,8,0)
//Macro to zero a 64bit value
#define M_zero64(x) x.w[0]=0L;x.w[1]=0L
#define M_iszero64(x) ((x.w[0]==0L)&&(x.w[1]==0L))
#define bit64_set(x,i) x.b[i>>3]|=(1<<(i&7))

int64 cast32x64(int32 a) {
   //routine to convert a 32bit int to 64bit
   int64 temp;
   int8 i;
   temp.w[0]=a;
   //and clear the top half
   temp.w[1]=0L;
   return temp;
}

int64 I_A_LT_B(int64 a,int64 b) {
   //Internal routine to _compare_ two 64 bit values
   //Actually performs subtraction, and returns this, with the 'borrow'
   //flag in the global variable 'BORROW'. Performs a-b, hence flag is
   //set if A less than B
   M_sub64x64(a,b);
   if (CARRY==0) BORROW=TRUE;
   else BORROW=FALSE;
   return a;
}

int64 add64x64(int64 a,int64 b) {
   //simple 64 bit addition call - returns (a+b)
   M_add64x64(a,b);
   return a;
}

int64 sub64x64(int64 a,int64 b) {
   //64 bit subtraction call as above - returns (a-b)
   M_sub64x64(a,b);
   return a;
}

int64 mult32x32(int32 a,int32 b) {
   //Routine to multiply two 32bit values with a 64bit result
   int64 temp2;
   int8 i;
   //zero output
   M_zero64(temp2);
   //Not trying to break any records for efficiency, so all in C, and not using
   //hardware multiply
   //start by moving the int32, into the low half of the int64
   scratch64=cast32x64(b);
   //Now need to work through all 32 bits in the 'a' variable
   for (i=0;i<32;i++) {
      //if source bit in 'a' is one, perform addition
      if (bit_test(a,i))
         M_add64x64(temp2,scratch64);
      //rotate the second value here
      M_shiftleft64(scratch64);
   }
   return temp2;
}

int64 div64x64(int64 a,int64 b) {
   //Routine to divide 'a' by 'b' in 64bit arithmetic
   //returns with result, leaving remainder in the scratch64
   int8 bitno=0,ctr;
   int64 temp;
   if (M_iszero64(b)) {
      if (!M_iszero64(a)) {
         //need maximum result
         temp.w[0]=temp.w[1]=0xFFFFFFFF;
         M_zero64(scratch64);
         return temp;
      }
      //Else 0/0=1
      M_zero64(temp);
      M_zero64(scratch64);
      temp.b[0]=1;
      return temp;
      //return 1
   }
   M_zero64(temp);
   bitno=0;
   //Now position divisor to suit find top bit in A, and rotate b till it's
   //top bit is in the same position
   if (a.w[1]!=0) {
      for(ctr=31;!bit_test(a.w[1], ctr);ctr--) ;
      //Now rotate b till it's top bit matches.
      while (!bit_test(b.w[1], ctr)) {
         M_shiftleft64(b);
         ++bitno;
      }
   }
   else {
      for(ctr=31;!bit_test(a.w[0], ctr);ctr--) ;
      bitno=ctr;
      //Now rotate b till it's top bit matches.
      while (!bit_test(b.w[1], ctr)) {
         M_shiftleft64(b);
         ++bitno;
      }
   }    
   //bitno now stores how far b had to rotate
   while (bitno) {
      //Loop for bitno bits, performing subtract, shift & test
      scratch64=I_A_LT_B(a,b);
      if (!BORROW) {
         a=scratch64;
         //Set output bit if no borrow
         bit64_set(temp,bitno);
      }
      if (M_iszero64(a)) break;
      M_shiftright64(b);
      bitno--;
   }
   scratch64=a;
   return temp;
}
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: Nocturno en 09 de Febrero de 2010, 09:09:01
Pues lo veo complicado, no hay ninguna función ahí para convertirlo a decimal...

Llevo toda la mañana pensando en el tema y no se me ha encendido la bombilla.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: jfh900 en 09 de Febrero de 2010, 09:26:32
Y no te sirve:

int64 Var;

Var := var_8 * pow(2,32)+var_32;

printf("%f",Var);

Donde var_8 y var_32 son los valores que recibes.

Un saludo
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: J1M en 09 de Febrero de 2010, 09:32:45
o_0 ... me gusta y tiene sentido!
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: Nocturno en 09 de Febrero de 2010, 09:34:54
Pues yo me pierdo: ¿int64 en CCS?
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: J1M en 09 de Febrero de 2010, 09:39:26
Teóricamente está definido en la ayuda... aunque solo como signed.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: jfh900 en 09 de Febrero de 2010, 10:16:11
Pues yo me pierdo: ¿int64 en CCS?

Tienes razón, en CCS no está definida el int64.

Un saludo
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 10:34:57
A lo mejor la pregunta inicial está mal planteada. Parece que la pregunta debería ser: Dado un número de n bits de longitud ¿como se pueden obtener los dígitos de la cifra decimal equivalente, uno a uno?  :shock:
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: J1M en 09 de Febrero de 2010, 10:54:54
Ahí está Diego, complicando el asunto... jejeje

Jesús, como q no está definido? qué versión usas? en la última, aparece en la ayuda, he probado a hacer una suma y comerselo se lo come, el código que aparece en ASM pudiera ser cierto (aunque no lo he comprobado)... ahora el que me he perdido he sido yo!

Edito:

PD, PD, PD... en la prueba estaba usando un dspic ya que andaba trabajando con uno... y por eso será que me ha compilado. Por lo que dice CCS los Pic24 y los Dspic si que soportan los 64bits:
http://www.ccsinfo.com/content.php?page=PIC24-dsPIC-features&navcode=/rhCFeatures24

No pasa con los demás:
http://www.ccsinfo.com/content.php?page=overview&navcode=/rhCFeatures10

Respondido me hayo...
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 10:57:43
En la 4.093 no aparece. int64 tira el error de Undefined identifier.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: J1M en 09 de Febrero de 2010, 11:01:45
Es que a veces me voy a la parra y ni me doy cuenta, mira el 'edito' que he añadido.

'Me se' pasa la pasta! XDD aioooss
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: aitopes en 09 de Febrero de 2010, 11:05:34
Hola Diego!
Que problema "peliagudo".  :5]

Pensando en voz alta: cada 4 digitos binarios tienes uno en decimal. Tu chorizo de 40 digitos son 10 digitos Hexa. ¿No te es mas facil trabajarlos (al menos mentalmente) de esa forma? (creo que no, pero por ahi te da alguna idea).

Existe un algoritmo que se llama algo asi como "recorre y suma 3 (http://www.engr.udayton.edu/faculty/jloomis/ece314/notes/devices/binary_to_BCD/bin_to_BCD.html)" que podria aplicarse a este problema. En el link que te pongo ( http://www.engr.udayton.edu/faculty/jloomis/ece314/notes/devices/binary_to_BCD/bin_to_BCD.html) está bastante explicado.

Asi convertirias FF a 255

(http://www.engr.udayton.edu/faculty/jloomis/ece314/notes/devices/binary_to_BCD/bcd02.png)

Es una idea nomas...pensando en voz alta  :lol:
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: erdanieee en 09 de Febrero de 2010, 11:14:20
Buenas RedPic,

he estado dándole vueltas y al final era más sencillo de lo que parecía. Pero primero necesitas crear con un programa externo una matriz de 40x13 (número de bits a convertir por número de dígitos de 2^40), de forma que en las filas tengas el número 2^n (n de 0 a 40) separado en unidades, decenas, centenas, ... y en cada columna coincidan todas las unidades, decenas, ... Lo explico mejor con un ejemplo. Si quisieras convertir un número de 8 bits (en vez de 40) la matriz sería esta:

m = {
        {0,0,1},    //2^0
   {0,0,2},   //2^1
   {0,0,4},   //2^2
   {0,0,8},   //2^3
   {0,1,6},   //2^4
   {0,3,2},   //2^5
   {0,6,4},   //2^6
   {1,2,8}      //2^7   
     }

ahora el resto es sencillo. Para hayar las unidades del 10000111, sumaremos todas las unidades de nuestra matriz, excepto de aquellas que correspondan a un cero y nos quedamos con las unidades del resultado. El exceso se acumula para las decenas...

m = {    {0,0,1},    1
   {0,0,2},   1
   {0,0,4},   1
   {0,0,8},   0
   {0,1,6},   0
   {0,3,2},   0
   {0,6,4},   0
   {1,2,8}      1
     }

unidades = 1 + 2 + 4 + 8 = 15
decenas  = 0 + 0 + 0 + 2 + 1 = 3
centenas = 0 + 0 + 0 + 1 = 1

Y efectívamente, el 10000111 en binario corresponde al 135 en decimal.

Espero te sirva.
saludos!!
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RICHI777 en 09 de Febrero de 2010, 11:36:13
Hola Red, lo que necesitas es implementar matematica de multiprecisión. Para convertir el numero deberas aplicar sucesivamente la division de multiprecisión entre el numero y 10, cada digito ASCII es el resto de la operación, esto se hace de manera similar a como lo harias con lapiz y papel. Lamentablemente en la mayoria de los casos estas funciones son implementadas en assembler. Una excelente referencia es el libro de Knuts Tomo 1.

Saludos !
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: droky en 09 de Febrero de 2010, 12:23:48
Hola,
Si tienes capacidad de proceso, te planteo la solución de sumar en papel.
Coges tu ristra y conviertes a decimal los primeros 32 bits ( hasta aquí el CCS opera)
Ahora te quedan los 8 restantes bits hasta los 40 bits de tu necesidad.
Haz una suma "ASCII".
Supón que tu dato es:
01000001-11111111111111111111111111111111
En un string tienes "2147483648" que es tu valor de los primeros 32 bits a decimal-ASCII
Y tienes que sumarle:
2^32 = 4294967296
2^33 = 8589934592
2^34 = 17179869184
2^35 = 34359738368
2^36 = 68719476736
2^37 = 137438953472
2^38 = 274877906944
2^39 = 549755813888
dependiendo de si el bit correspondiente (32-39) es 1 ó 0.
Como con las funciones de seno y coseno, implementas una tabla, pero en este caso con los dígitos ASCII de los valores de 2^32 hasta 2^39 o haces unos arrays, como prefieras en RAM o en ROM.
Entonces tu dato es:
01000001-11111111111111111111111111111111

b0-b31=11111111111111111111111111111111 = 2147483648 en decimal que lo guardas en una variable tipo var1[32]="2147483648"
b32 = 1? sí. Hacemos la suma "ASCII" de "4294967296" con "2147483648" .
Cogemos el valor decimal del ASCII var1[0] ( que es var[0]-30 ) , se lo sumas al m[0] de m[]="4294967296" y la llevada te la guardas para la siguiente    cifra. Esto lo implementas en un bucle muy sencillo con una variable para la llevada. Al terminar, te quedará en el array resultado[]="6442450944" que vas a seguir "sumando en ASCII"
b33=1? no, seguimos
b34=1? no, seguimos
b35=1? no, seguimos
b36=1? no, seguimos
b37=1? no, seguimos
b38=1? sí. Hacemos la suma "ASCII" de "6442450944" con "274877906944" .
b39=1? no, terminamos. En resultado[] tenemos un array ASCII de valor resultado[]="281320357888"

Coste máx. de la operación 12*8 sumas =96 operaciones de suma de 8 bits y 8 comparaciones
Si implementas la tabla en ROM son 96 posiciones de ROM y necesitas 2 arrays de 12 bytes en RAM para hacer la suma ASCII

El método es el mismo que dibujar los números en un papel en una columna y sumarlos cifra a cifra. Mentalmente conviertes el dígito en su valor decimal y aquí el valor ASCII en su valor decimal (ya sabemos, restando 30 )
Espero haber sido claro.
Salu2

Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: Nocturno en 09 de Febrero de 2010, 12:33:39
¡Geniales!, me encantan los métodos de Droky y erdanieee.

¡Estoy oxidado!  :(
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 17:19:03
¡Guau! ¡Guau! ¡Guau!  :) :) :)

erdanieee, droky y los demás amigos: sabía que podía confiar en ustedes.

Voy a intentar implementar un test con el método de dorky a ver si no me consume mucha ROM ...

Añado: Veo muchas posibilidades en lo que Droky llama Suma "ASCII" ...  :mrgreen:
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: MGLSOFT en 09 de Febrero de 2010, 17:35:39
Diego:
Es el codigo de una tarjeta magnética o un touch lo que intentas sacar por el puerto??
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 09 de Febrero de 2010, 17:38:00
Si, Marcos, es el código de una Tarjeta Prox. de 125 Khz que me da 40 bits como código.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: MGLSOFT en 09 de Febrero de 2010, 17:42:42
El codigo de los Ibutton de cuantos bits es??
En el ejemplo de CCS tendrias como hacerlo mas facil si es parecido en longitud... :mrgreen:
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: migsantiago en 09 de Febrero de 2010, 19:21:40
Hola

Podría hacerse un truco... convencer a PCH (pic18) de que las variables int64 existen. Las definiciones vienen dadas en el archivo stdint.h.

Código: [Seleccionar]
#if defined(__PCD__)
//#define INT_LEAST24_MAX  (8388607)
//#define INT_LEAST24_MIN  (-8388608)
//#define UINT_LEAST24_MAX (16777215)

#define INT_LEAST64_MAX  (9223372036854775807)
#define INT_LEAST64_MIN  (-9223372036854775808)
#define UINT_LEAST64_MAX (18446744073709551615)
#endif

Habría que ver si PCH está preparado para manejar valores tan grandes.
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: sal0m0n en 16 de Febrero de 2010, 22:54:36

Cogemos el valor decimal del ASCII var1[0] ( que es var[0]-30 ) , se lo sumas al m[0] de m[]="4294967296" y la llevada te la guardas para la siguiente    cifra.
........

Mentalmente conviertes el dígito en su valor decimal y aquí el valor ASCII en su valor decimal (ya sabemos, restando 30 )
Espero haber sido claro.
Salu2



no entendia eso de convertir el valor ASCII de la variable, el truco esta en que es un string!

se supone entonces que el resultado va a quedar en una cadena de caracteres??

que me dicen de migsantiago?? seria asi de simple? engañando al compilador modificando el archivo stdint.h???

salu2
Título: Re: ¿Como estáis de aritmética de mas de 32 bits? (En CCS)
Publicado por: RedPic en 14 de Noviembre de 2011, 07:19:11
Droky, eres un genio. Te debo una (otra).  :-/ :-/ :-/

Casi dos años después me he visto en la obligación de retomar este tema, aunque en este caso con 56 bits en vez de 40, y tu solución es la solución.

Efectivamente, he realizado la conversión "directa" de los 32 bits de menor peso, lo he guardado en decimal sobre un string de "resultado" utilizando el sprintf() y después con una tabla de potencias de dos para los bits de mas peso, entre el 33 y el 56, he ido sumando en ASCII exactamente igual que hacíamos en el colegio "con manzanas"  :oops: :oops: :oops:   :D :D :D

Como dicen que "de bien nacidos es ser agradecidos" aquí tienes mi agradecimiento público y efusivo. Gracias, gracias, muchas gracias.  :)

Este es el código:

Nota: Los bits los tengo en un bitsArray y los extraigo uno a uno mediante la función get_array_bit()

Código: C#
  1. int8  i,j,d1,d2,r,carry;
  2.    int32 first_code;
  3.    char  OutPut[19]="000000000000000000";
  4.    const char  Pots2[24][19]={      
  5.                     "036028797018963968",
  6.                     "018014398509481984",
  7.                     "009007199254740992",
  8.                     "004503599627370496",
  9.                     "002251799813685248",
  10.                     "001125899906842624",
  11.                     "000562949953421312",
  12.                     "000281474976710656",
  13.                     "000140737488355328",
  14.                     "000070368744177664",
  15.                     "000035184372088832",
  16.                     "000017592186044416",
  17.                     "000008796093022208",
  18.                     "000004398046511104",
  19.                     "000002199023255552",
  20.                     "000001099511627776",
  21.                     "000000549755813888",
  22.                     "000000274877906944",
  23.                     "000000137438953472",
  24.                     "000000068719476736",
  25.                     "000000034359738368",
  26.                     "000000017179869184",
  27.                     "000000008589934592",
  28.                     "000000004294967296"};
  29.    
  30.    // Primeros 32 bits. conversión directa.
  31.    first_code=0;
  32.    for(i=55;i>23;i--){
  33.      //bit_clear(Code,31-i);
  34.      if(get_array_bit(bitsArray,i)==1){
  35.        bit_set(first_code,55-i);
  36.      }
  37.    }
  38.    sprintf(OutPut,"%18Lu",first_code);
  39.    replace_char(' ','0',OutPut);
  40.    printf("<%s>\r\n",OutPut);
  41.    // Últimos 24 bits. conversión por sumas sucesivas mediante tabla de potencias de 2.
  42.    for(i=0;i<24;i++){
  43.       if(get_array_bit(bitsArray,i)==1){
  44.          carry = 0;
  45.          for(j=17;j>0;j--){
  46.             d1=OutPut[j]-'0';
  47.             d2=Pots2[i][j]-'0';
  48.             r = (int) (d1 + d2) + carry;
  49.             carry = 0;
  50.             if(r > 9){
  51.                r -= 10;
  52.                carry = 1;
  53.             }
  54.             printf("<%u/%u : %u + %u = %u Carry %u>\r\n",i,j,d1,d2,r,carry);
  55.             OutPut[j]=r+'0';
  56.          }
  57.       }
  58.    }      
  59.    printf("<%s>\r\n",OutPut);


Le he metido printf()´s por medio para poder monitorizar la secuencia completa. Aquí tenéis un ejemplo de su ejecución:

Código: ASM
  1. Dados los bits: 10000000001000010100000000000010100000100011011000000100
  2. Correspondientes al decimal : 036065355822675460
  3. <Bit/ASCII : Sumando1 + Sumando2 = Resultado Carry Acarreo>
  4.  
  5. <000000000042087940>
  6. <0/17 : 0 + 8 = 8 Carry 0>
  7. <0/16 : 4 + 6 = 0 Carry 1>
  8. <0/15 : 9 + 9 = 9 Carry 1>
  9. <0/14 : 7 + 3 = 1 Carry 1>
  10. <0/13 : 8 + 6 = 5 Carry 1>
  11. <0/12 : 0 + 9 = 0 Carry 1>
  12. <0/11 : 2 + 8 = 1 Carry 1>
  13. <0/10 : 4 + 1 = 6 Carry 0>
  14. <0/9 : 0 + 0 = 0 Carry 0>
  15. <0/8 : 0 + 7 = 7 Carry 0>
  16. <0/7 : 0 + 9 = 9 Carry 0>
  17. <0/6 : 0 + 7 = 7 Carry 0>
  18. <0/5 : 0 + 8 = 8 Carry 0>
  19. <0/4 : 0 + 2 = 2 Carry 0>
  20. <0/3 : 0 + 0 = 0 Carry 0>
  21. <0/2 : 0 + 6 = 6 Carry 0>
  22. <0/1 : 0 + 3 = 3 Carry 0>
  23. <10/17 : 8 + 2 = 0 Carry 1>
  24. <10/16 : 0 + 3 = 4 Carry 0>
  25. <10/15 : 9 + 8 = 7 Carry 1>
  26. <10/14 : 1 + 8 = 0 Carry 1>
  27. <10/13 : 5 + 8 = 4 Carry 1>
  28. <10/12 : 0 + 0 = 1 Carry 0>
  29. <10/11 : 1 + 2 = 3 Carry 0>
  30. <10/10 : 6 + 7 = 3 Carry 1>
  31. <10/9 : 0 + 3 = 4 Carry 0>
  32. <10/8 : 7 + 4 = 1 Carry 1>
  33. <10/7 : 9 + 8 = 8 Carry 1>
  34. <10/6 : 7 + 1 = 9 Carry 0>
  35. <10/5 : 8 + 5 = 3 Carry 1>
  36. <10/4 : 2 + 3 = 6 Carry 0>
  37. <10/3 : 0 + 0 = 0 Carry 0>
  38. <10/2 : 6 + 0 = 6 Carry 0>
  39. <10/1 : 3 + 0 = 3 Carry 0>
  40. <15/17 : 0 + 6 = 6 Carry 0>
  41. <15/16 : 4 + 7 = 1 Carry 1>
  42. <15/15 : 7 + 7 = 5 Carry 1>
  43. <15/14 : 0 + 7 = 8 Carry 0>
  44. <15/13 : 4 + 2 = 6 Carry 0>
  45. <15/12 : 1 + 6 = 7 Carry 0>
  46. <15/11 : 3 + 1 = 4 Carry 0>
  47. <15/10 : 3 + 1 = 4 Carry 0>
  48. <15/9 : 4 + 5 = 9 Carry 0>
  49. <15/8 : 1 + 9 = 0 Carry 1>
  50. <15/7 : 8 + 9 = 8 Carry 1>
  51. <15/6 : 9 + 0 = 0 Carry 1>
  52. <15/5 : 3 + 1 = 5 Carry 0>
  53. <15/4 : 6 + 0 = 6 Carry 0>
  54. <15/3 : 0 + 0 = 0 Carry 0>
  55. <15/2 : 6 + 0 = 6 Carry 0>
  56. <15/1 : 3 + 0 = 3 Carry 0>
  57. <17/17 : 6 + 4 = 0 Carry 1>
  58. <17/16 : 1 + 4 = 6 Carry 0>
  59. <17/15 : 5 + 9 = 4 Carry 1>
  60. <17/14 : 8 + 6 = 5 Carry 1>
  61. <17/13 : 6 + 0 = 7 Carry 0>
  62. <17/12 : 7 + 9 = 6 Carry 1>
  63. <17/11 : 4 + 7 = 2 Carry 1>
  64. <17/10 : 4 + 7 = 2 Carry 1>
  65. <17/9 : 9 + 8 = 8 Carry 1>
  66. <17/8 : 0 + 4 = 5 Carry 0>
  67. <17/7 : 8 + 7 = 5 Carry 1>
  68. <17/6 : 0 + 2 = 3 Carry 0>
  69. <17/5 : 5 + 0 = 5 Carry 0>
  70. <17/4 : 6 + 0 = 6 Carry 0>
  71. <17/3 : 0 + 0 = 0 Carry 0>
  72. <17/2 : 6 + 0 = 6 Carry 0>
  73. <17/1 : 3 + 0 = 3 Carry 0>
  74. <036065355822675460>

Sois lo mejor.  :P :P :P