johan
tengo los siguientes datos
uint8_t d1=0x01;
uint8_t d2=0x02;
Quiero combinarlos como uint16_t
como
uint16_t wd = 0x0201;
¿Cómo puedo hacerlo?
Puede utilizar operadores bit a bit:
uint16_t wd = ((uint16_t)d2 << 8) | d1;
Porque:
(0x0002 << 8) | 0x01 = 0x0200 | 0x0001 = 0x0201
-
Sí, lo es.
d2
primero debe emitirse (de lo que se ocupa la publicación editada).–Jonathan Grynspan
6 de marzo de 2013 a las 14:26
-
@LuchianGrigore: Oh, sí, lo he olvidado. Gracias.
– md5
6 de marzo de 2013 a las 14:26
-
@LuchianGrigore & JonathanGrynspan No necesariamente, ya que
d2
primero es ascendido aint
(que es al menos 16 bits). Pero bien, todavía podría ser UB siint
en realidad era solo 16 bits en su plataforma y(int)d2 << 8
desbordaría el no negativoint
rango.– Christian Raú
06/03/2013 a las 14:30
-
No veo cómo el elenco mejoraría algo. Supongamos que uint16_t tiene un rango de conversión más bajo que
int
, entonces no ha resuelto nada con el elenco, el operando izquierdo aún se promovería implícitamente a (firmado) int. Pero como no hay forma de que pueda arrojar un valor negativo, el comportamiento de este código y el original siempre está bien definido.– Lundin
6 de marzo de 2013 a las 14:31
-
Mi respuesta también se encarga de eso.
– R.. GitHub DEJA DE AYUDAR A ICE
6 de marzo de 2013 a las 14:31
La forma más sencilla es:
256U*d2+d1
-
Oh Ahora realmente tenemos un caso de uso para las operaciones bit a bit y todavía te apegas a la aritmética aburrida. 😉
– Christian Raú
6 de marzo de 2013 a las 14:33
-
<<8
y*256
son operaciones idénticas, excepto que la primera tiene un comportamiento indefinido en más casos y, por lo tanto, generalmente no es deseable. Casi nunca hay una razón para usar el<<
o>>
operadores a menos que el operando de la derecha sea variable (en cuyo caso tiene un buen operador de exponenciación).– R.. GitHub DEJA DE AYUDAR A ICE
6 de marzo de 2013 a las 14:39
-
Sí, ese comentario fue de naturaleza bastante humorística.
– Christian Raú
06/03/2013 a las 14:40
-
¿Cómo funciona esta clasificación de respuestas? ¿Por qué esto siempre aparece en la parte inferior de la página?
– Brett Hale
14 de abril de 2016 a las 10:22
Lundin
Esto es bastante simple. No necesitas moldes, no necesitas variables temporales, no necesitas magia negra.
uint8_t d1=0x01;
uint8_t d2=0x02;
uint16_t wd = (d2 << 8) | d1;
Este siempre es un comportamiento bien definido ya que d2 siempre es un valor positivo y nunca se desborda, siempre que d2 <= INT8_MAX
.
(INT8_MAX se encuentra en stdint.h).
-
… excepto cuando es no 0x7F (ver 5.2.4.2)
– autista
6 de marzo de 2013 a las 14:53
-
@modifiablelvalue Énfasis en en la práctica. Todas las implementaciones sanas usan wchar_t para números enteros más grandes si esa es su preocupación. Si su preocupación es el complemento de uno o las CPU de signo y magnitud, ¡déjeme saber dónde comprarlas porque yo también quiero una!
– Lundin
6 de marzo de 2013 a las 14:58
-
INT8_MAX
es 127. Es cierto qued2<<8
puede demostrarse que no se desborda cuandod2<=127
pero la razón es queINT_MAX
se requiere que sea al menos 32767 pero no se requiere que sea más grande.– R.. GitHub DEJA DE AYUDAR A ICE
6 de marzo de 2013 a las 15:17
-
La desventaja del modelo de stackoverflow es que la mayor parte de esta discusión ahora se vuelve basura debido a una edición de la publicación original. Proporcionando INT_MAX == 32767, INT8_MAX es el valor máximo por coincidencia. Cuando INT_MAX >= 32768, INT8_MAX no tiene sentido.
– autista
6 de marzo de 2013 a las 15:18
-
@Lundin El peligro no es necesariamente cambiando a los bits de signo; Usar un valor que no se puede representar como un
int
en una expresión que tieneint
escribe parece una descripción más apropiada para este comportamiento indefinido.– autista
06/03/2013 a las 15:31
(uint16_t)((d2 << 8) + (d1 & 0x00ff))