Guía de ejercicios
Representación de datos
Recordad que, excepto cuando se indique lo contrario, en los ejercicios de este capítulo queda limitado el uso de operadores y estructuras de C a:
- operaciones sobre bits (
&,|,~) - desplazamientos a izquierda y derecha (
<<,>>) - sumas y restas (
+,-) - igualdad y desigualdad (
==,!=)
Clase 20/03
2.61
Escribir expresiones en C que devuelvan 1 cuando cada una de las las
siguientes condiciones sean verdaderas, o 0 cuando no. Asumir que x
es de tipo uint32_t.
- Si cualquier bit de
xes 1 - Si cualquier bit de
xes 0 - Si cualquier bit en el byte menos significativo de
xes 1 - Si cualquier bit en el byte más significativo de
xes 0
El código debe seguir las reglas de programación para enteros a
nivel bit. Como restricción adicional, no se permite el uso de
operadores de igualdad (==) y desigualdad (!=).
2.66
Implementar la función:
1
int leftmost_one(uint32_t val);
que devuelve una máscara indicando el bit más significativo en val que
está a 1. Por ejemplo, se devuelve 0x8000 para val=0xFF00 y 0x4000
para val=0x6600.
2.72
La siguiente función copia un valor de tipo int en un buffer
de tamaño dado maxbytes bytes (obsérvese que la comprobación del
tamaño se hace, de manera algo artificial, mediante una resta):
1
2
3
4
void copy_int(int val, void *buf, int maxbytes) {
if (maxbytes - sizeof(val) >= 0)
memcpy(buf, &val, sizeof(val));
}
Testeando el código en detalle, se puede ver que el valor siempre se copia al buffer, includo cuando maxbytes tiene un valor muy chico.
- Explicar por qué el condicional siempre da verdadero. (Ayuda: El
operador
sizeofdevuelve un valor de tiposize_t.) - Reescribir el condicional de modo que funcione correctamente.
Clase 13/03
2.60
Implementar la función:
1
uint32_t replace_byte(uint32_t val, int i, uint8_t rempl);
que devuelve el entero val con su i-ésimo byte cambiado al valor de rempl.
Los bytes se numeran asignando i=0 al byte menos significativo e i=3 al más significativo.
2.64
Implementar la función:
1
int any_odd_one(uint32_t val);
que devuelve 1 si val tiene algún bit impar a 1, o 0 si todos sus bits
impares están a 0. Por ejemplo, la función devuelve 0 para val=5 y 1 para val=6.
2.68
Implementar la función:
1
uint32_t lower_one_mask(int n);
que, dado un entero entre 1 y 32 (inclusive) devuelve una máscara con ese
número de bits activos (comenzando por el menos significativo). Ejemplos: para
n=6, la función devuelve 0x3F.