es posible concatenar un array byte?

Iniciado por Belial & Grimoire, 31 Enero 2014, 06:33 AM

0 Miembros y 1 Visitante están viendo este tema.

Yoel Alejandro

#10
x64Core, es cierto lo que dices, la rotación es más rápida.

El código podría entonces quedar así, para concatenar 2 bytes en un entero de 16bits:


unsigned short word1;

word1 = (unsigned short) buffer[1] << 8 + buffer[0];


Para concatenar 4 bytes bajo la forma de un entero de 32 bits, sería:


unsigned long int dword1;
char buffer[4];

/* luego convertimos */
dword1 = (unsigned long )buffer[3] << 24 + (unsigned long )buffer[2] << 16 + (unsigned long )buffer[1] << 8 + buffer[0];


Pero yo no sabría garantizar de forma absoluta la infalibilidad de este código. Lei en un libro que las operaciones a nivel de bits son "altamente dependientes de máquina", por lo que pudieran tener un comportamiento indeseado dependiendo de la arquitectura.

Como dijo otro usuario, en algunos sistemas el byte bajo es el menos significativo, mientras en otros sistemas es el más significativo, por eso cuando hablamos de "desplazamiento de bits hacia la izquierda", ¿desplaza al byte más alto o al más bajo?

Pero suponemos que al hacer el cast explícito (unsigned sort), ---el cual es indispensable en cualquier caso---, el compilador entiende que la variable en cuestión ocupa dos bytes de memoria y debe hacer el desplazamiento de bits hacia el byte más significativo, sea que este ocupe la posición más baja o más alta de memoria, dependiendo de la máquina donde esté implementado el programa. Y similarmente con el caso de los enteros de 32 bits.

Pero es una suposición mía, no lo puedo asegurar al 100%. Por ello propuse la solución basada en multiplicación, que creí más segura.
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

x64core

Cita de: yoel_alejandro en  9 Febrero 2014, 18:12 PM
x64Core, es cierto lo que dices, la rotación es más rápida.

El código podría entonces quedar así, para concatenar 2 bytes en un entero de 16bits:


unsigned short word1;

word1 = (unsigned short) buffer[1] << 8 + buffer[0];


Para concatenar 4 bytes bajo la forma de un entero de 32 bits, sería:


unsigned long int dword1;
char buffer[4];

/* luego convertimos */
dword1 = (unsigned long )buffer[3] << 24 + (unsigned long )buffer[2] << 16 + (unsigned long )buffer[1] << 8 + buffer[0];


Pero yo no sabría garantizar de forma absoluta la infalibilidad de este código. Lei en un libro que las operaciones a nivel de bits son "altamente dependientes de máquina", por lo que pudieran tener un comportamiento indeseado dependiendo de la arquitectura.

Como dijo otro usuario, en algunos sistemas el byte bajo es el menos significativo, mientras en otros sistemas es el más significativo, por eso cuando hablamos de "desplazamiento de bits hacia la izquierda", ¿desplaza al byte más alto o al más bajo?

Pero suponemos que al hacer el cast explícito (unsigned sort), ---el cual es indispensable en cualquier caso---, el compilador entiende que la variable en cuestión ocupa dos bytes de memoria y debe hacer el desplazamiento de bits hacia el byte más significativo, sea que este ocupe la posición más baja o más alta de memoria, dependiendo de la máquina donde esté implementado el programa. Y similarmente con el caso de los enteros de 32 bits.

Pero es una suposición mía, no lo puedo asegurar al 100%. Por ello propuse la solución basada en multiplicación, que creí más segura.

Estoy interesado en qué fuente es quien dice que las operaciones a nivel de bits son altamente dependiente de maquina.
Me pregunto si se refieren a la arquitectura ( Little, Endian ) espero que no...


x64core

Aun esperando el enlace donde dice eso yoel_alejandro. Además no habia visto esto:
Citarword1 = (unsigned short) buffer[1] << 8 + buffer[0];

Como dije, es mejor la manipulacion de bits, se puede sustituir la operacion de suma con el operador OR, lo cual vendria ser exactamente
la misma operacion que escribí en mi primer 'post'.

Yoel Alejandro

#13
Estimado, Deitel&Deitel, "Cómo programar en C/C++", segunda edición. en Español, 1995.

En el tema "Estructuras, uniones, manipulaciones de bits y enumeraciones", p. 407, reza:

Citar
"(...) También los programas de las secciones 10.9 y 10.10 fueron probados en una Macintosh de Apple usando Thisk C y una PC compatible, utilizando Borland C++. Ambos sistemas utilizan enteros de 16 bits (2 bytes). Dada la naturaleza de dependencia de la máquina de las manipulaciones a nivel de bits, estos programas pudieran no funcionar en su sistema"
Como vez, lo dicen Deitel&Deitel (dos profesores con décadas de experiencia enseñando C), y no yo. Por eso digo que yo no se ...

Por otra parte, ten cuidado x64 con que la suma aritmética no siempre es igual a la suma lógica. Los resultados no son iguales en caso de que se practique una suma binaria con acarreo. Por ejemplo, la suma aritmética de b'01' y b'01' será b'10' (2 en decimal). En cambio, la misma suma lógica produce b'01'. En nuestro caso, por la teoría subyacente de sistemas numéricos sabemos que debe ser la suma aritmética.

============
Por último, respecto a lo extraño de la sentencia:

Código (cpp) [Seleccionar]

word1 = (unsigned short) buffer[1] << 8 + buffer[0];


la acabo de probar en mi compilador (GNU gcc acorde con C99) y me dice que está bien, sólo recomienda revisar la prioridad de los operadores. Entonces, revisando más a fondo el asunto recorde que el operador de suma posee mayor prioridad que el de desplazamiento (sorry por el olvido  :-[), por lo que lo correcto sería en todo caso:

Código (cpp) [Seleccionar]

word1 = ((unsigned short) buffer[1] << 8) + buffer[0];


y similarmente con las demás.
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

x64core

Cita de: yoel_alejandro en 11 Febrero 2014, 02:36 AM
Estimado, Deitel&Deitel, "Cómo programar en C/C++", segunda edición. en Español, 1995.

En el tema "Estructuras, uniones, manipulaciones de bits y enumeraciones", p. 407, reza:
Como vez, lo dicen Deitel&Deitel (dos profesores con décadas de experiencia enseñando C), y no yo. Por eso digo que yo no se ...

Por otra parte, ten cuidado x64 con que la suma aritmética no siempre es igual a la suma lógica. Los resultados no son iguales en caso de que se practique una suma binaria con acarreo. Por ejemplo, la suma aritmética de b'01' y b'01' será b'10' (2 en decimal). En cambio, la misma suma lógica produce b'01'. En nuestro caso, por la teoría subyacente de sistemas numéricos sabemos que debe ser la suma aritmética.

============
Por último, respecto a lo extraño de la sentencia:

Código (cpp) [Seleccionar]

word1 = (unsigned short) buffer[1] << 8 + buffer[0];


la acabo de probar en mi compilador (GNU gcc acorde con C99) y me dice que está bien, sólo recomienda revisar la prioridad de los operadores. Entonces, revisando más a fondo el asunto recorde que el operador de suma posee mayor prioridad que el de desplazamiento (sorry por el olvido  :-[), por lo que lo correcto sería en todo caso:

Código (cpp) [Seleccionar]

word1 = ((unsigned short) buffer[1] << 8) + buffer[0];


y similarmente con las demás.

Hola, perdon por la tardanza; habia olvidado el tema. alejandro, pues claro que las operaciones que se pueden hacer con los operadores
logicos no pueden reemplazar a los operadores aritmeticos, pero en este caso era simplemente movimientos de valores enteros ( No en
realidad, era de un byte ) así que lo mejor es hacerlo mediante operadores logicos, sino pues, talvez puedes decirnos algo mucho más
justificado de porqué hacerlo de otra manera ( vamos, estamos en el 2014 ).

Por cierto,  puede que nos quieras decir cómo en tu suma logica el binario 01 + 01 daria como resultado 01?
( ¿No crees que te haz empatanado un poco? )