El objetivo de esta práctica es ganar agilidad en la conversión y trabajo con números a ojo y saber cómo utilizar código C para no perder la cabeza. La conversión a ojo suele ser muy útil en el momento de leer código asembler ya que en general los números estarán representados en hexadecimal o en binario.
-
Convertir los siguientes números en representación decimal a binario (16bits)
- 18265
- 7810
- 51007
- 66425
- 31530
- 19725
- 5736
- 423
-
Escribir un programa en C que, utilizando printf y scanf, resuelva el ejercicio anterior.
Hint: El siguiente código describe un programa que toma el número decimal ingresado por el usuario y lo imprime en la misma representación.
#include <stdio.h> int main(void) { unsigned int entered_number; printf("Enter a number in decimal: "); scanf("%u", &entered_number); printf("Decimal: %d\n", entered_number); return 0; }
-
Convertir los siguientes números en representación hexadecimal a binario (16bits)
- 0xdc2d
- 0x9b7a
- 0xfdd8
- 0xe882
- 0xe8b2
- 0x6e49
- 0x235e
- 0x3343
- 0x39d1
- 0xf093
-
Escribir un programa en C que utilizando printf y scanf resuelva el ejercicio anterior. El número debe ser ingresado en formato 0x1234.
Hint: utilizar los distintos formatos aceptados por la función printf y scanf.
-
Convertir los siguientes números en representación binaria a hexadecimal (16bits)
- 0b0100000110101101
- 0b0101100011001010
- 0b0001001001101110
- 0b1001010000100101
- 0b1000001101010110
- 0b1101010101101110
- 0b1010010001101110
- 0b0100100101011100
- 0b1011100110011010
- 0b0100010011011101
-
Escribir un programa en C que utilizando printf y scanf resuelva el ejercicio anterior. El número debe ser ingresado en formato 0b0100010011011101.
Hint: a falta de un formato específico para leer e imprimir números binarios, escribir primero una función que permita obtener el número representado en un string de 1s y 0s.
-
Escribir un programa en C que identifique el formato del número ingresado e imprima la representación de ese número en decimal, hexadecimal y binario.
-
Escribir un programa en C que imprima el tamaño de los siguientes tipos: int, unsigned int, unsigned long int, char, char *, float, double, float *, double *, y unsigned int *. Compilar el programa para una arquitectura de 32bits y una de 64bits para ver la diferencia.
Hint:
$ gcc -Wall -m32 programa.c -o programa_32.c
$ gcc -Wall -m64 programa.c -o programa_64.c
-
Escribir un programa en C que muestre el endianness de la plataforma en la que se ejecuta el programa.
Hint: read the book
-
Utilizar la herramienta qemu para ejecutar el programa en distintas arquitecturas.
Hint: pueden instalar las herramientas qemu-user-static gcc gcc-multilib-sparc64-linux-gnu o utilizar el dockerfile incluido en esta práctica.
$ gcc print_endianness.c --static -o print_endianness_x86_64
$ ./print_endianness_x86_64
$ sparc64-linux-gnu-gcc print_endianness.c --static -o print_endianness_sparc
$ qemu-sparc64-static print_endianness_sparc
-
Resolver los siguientes problemas de álgebra booleana.
- (~A) para:
- A = 0xac
- A = 0x11
- A = 0x23
- A = 0xde
- (A | B) para:
- A = 0xac ; B = 0x32
- A = 0x11 ; B = 0xaa
- A = 0x23 ; B = 0xff
- A = 0xde ; B = 0x13
- (A & B) para:
- A = 0xac ; B = 0x32
- A = 0x11 ; B = 0xaa
- A = 0x23 ; B = 0xff
- A = 0xde ; B = 0x13
- (A ^ B) para:
- A = 0xac ; B = 0x32
- A = 0x11 ; B = 0xaa
- A = 0x23 ; B = 0xff
- A = 0xde ; B = 0x13
- (~A) para:
-
Escribir un programa en C que utilizando printf y scanf resuelva el ejercicio anterior. Los números deben ser ingresados por separado en formato 0x1234.
-
Resolver los siguientes problemas de manejo de bits.
- (0xffe2 >> 3)
- (0xace2 << 5)
- (0x12e2 >> 2)
- (0xf1eb >> 1)
- (0xab12 << 6)
- (0x62ea >> 2)
-
Escribir una función en C que aproveche las operaciones de bits para setear (poner en 1) o clearear (poner en 0) un bit específico (index: 0, 1, 2, ...) dentro de una variable de 32bits. La variable modificada es devuelta por return de la función.
uint32_t set_bit_on_var(uint32_t var, size_t index);
-
Escribir en representación entera de 16bits con complemento a dos los siguientes números.
- 14772
- 12110
- -13483
- -8104
- 11518
- -29641
- -3188
- -19378
- 8566
- -4682
-
Convertir la siguiente representación binaria de 16bits a decimal, suponiendo primero que es una representación entera sin signo, luego una representación entera con signo en complemento a dos y finalmente una en complemento a uno.
- 0b1111000010010011
- 0b0011110100011101
- 0b1010011011010111
- 0b0110101001010111
- 0b1111001101000001
- 0b0100110000011011
- 0b1111001101001000
- 0b0110001100000011
- 0b1011101001101011
- 0b0100111110011011
-
Escribir una función en C que acepte por parámetro un número entero sin signo e imprima la representación entera con signo y sin signo. Probar la función con los siguientes números.
- 53888
- 47428
- 36650
- 1455
- 29128
- 36040
- 65536
- 52854
- 29626
- 46818
-
Asumiendo que las siguientes expresiones son evaluadas en una arquitectura de 32bits que utiliza aritmética en complemento a dos, resolver a que evalúan.
-2147483647-1 == 2147483648U-2147483647-1 < 2147483647-2147483647-1U < 2147483647-2147483647-1 < -2147483647-2147483647-1U < -21474836472147483647U > -2147483647-12147483647 > (int) 2147483648U-1 < 0U
Hint: escribir un programa en C que compruebe los resultados.
-
Escribir una función en C que tome como parámetro un número entero de 16bits con signo (short int), copie el valor a una variable de 32bits (int) e imprima su valor. Escribir un programa que utilice esta función y la escrita anteriormente que imprime la representación en memoria de la variable para ver cómo cambia en distintas arquitecturas utilizando como entrada los siguientes números.
Hint: utilizar qemu-sparc64-static para ejecutar el programa en arquitecturas big-endian
- 13528
- -11674
- 27091
- -15913
- 22782
- -8521
- 4874
- -698
- 13992
- 17396
-
Escribir una función en C que tome como parámetro un número entero de 32bits con signo (int), copie el valor a una variable de 32bits (short int) e imprima su valor. Escribir un programa que utilice esta función y la escrita anteriormente que imprime la representación en memoria de la variable para ver cómo cambia en distintas arquitecturas.
Hint: utilizar qemu-sparc64-static para ejecutar el programa en arquitecturas big-endian
- -1580948425
- 1870865340
- -107982815
- -157511958
- 742922907
- -1163069406
- 1813815629
- 223375263
- -625813639
- 403361717
-
Calcular la suma de las siguientes variables contra sí mismas suponiendo que son resueltas en una arquitectura de 32bits que utiliza una aritmética de complemento a dos (uint32_t). Indicar los casos en los que el resultado no es válido.
- 888678457
- 2851757120
- 1912450232
- 4079538690
- 4154371837
- 1988670315
- 442559150
- 2595390421
- 2860812492
- 515237114
-
Calcular la suma de las siguientes variables contra sí mismas suponiendo que son resueltas en una arquitectura de 32bits que utiliza una aritmética de complemento a dos (int32_t). Indicar los casos en los que el resultado no es válido.
- 9837
- 18328
- 30932
- -26481
- -24356
- 2260
- 25312
- -31865
- 4919
- -336
-
Escribir un programa en C que permita ingresar un número y resuelva los dos ejercicios anteriores. En caso de ser positivo calcular la suma tanto para una representación de uint32_t como para una representación int32_t.
-
Dadas las definiciones int a, b; y teniendo en cuenta que los enteros signados se representan en complemento a dos. Además, que las constantes INT_MIN e INT_MAX representan los valores mínimo y máximo que puede tener un entero de 32 bits, y la constante W = 31. Una las distintas descripciones con sus respectivas expresiones.
- Descripciones:
~a(complemento a uno)aa * 7(a < 0) ? 1 : -1
- Expresiones:
~(~a | (b ^ (INT_MIN + INT_MAX)))((a ^ b) & ~b) | (~(a ^ b) & b)1 + (a << 3) + ~a(a << 4) + (a << 2) + (a << 1)((a < 0) ? (a + 3) : a) >> 2a ^ (INT_MIN + INT_MAX)~((a | (~a + 1)) >> W) & 1~((a >> W) << 1)a >> 2
- Descripciones:
-
Convertir los siguientes números en representación decimal a binario de 16bits con punto fijo (1bit parte entera, 7bits parte fraccional). Para cada caso indicar el error por representación.
- 1.125
- 0.6723
- 0.98911
- 0.25
- 0.8984
- 0.743
- 1.832
- 0.902
- 0.12300
- 1.1111
-
Convertir los siguientes números representados en punto fijo a decimal.
- 11.101110
- 1101.1111
- 0110.1101
- 010000.01
- 100.10100
- 10.101010
- 1.1011100
- 10001.111
- 0.1110010
- 1.1000010
-
Convertir las representaciones binarias en punto flotante de 7 bits con 1 bit de signo, 3 bits de exponente y 3 de parte fraccionaria (seeefff) a sus valores numéricos fraccionarios.
- 0b1111101
- 0b0110101
- 0b0000110
- 0b1110000
- 0b1100100
Hint: identificar primero a qué caso de representación de punto flotante simil IEEE representan (valores normalizados, denormalizados, especiales).
-
Escribir un programa en C que permita realizar la identificación del caso de punto flotante para un valor con una codificación de 7 bits (seeefff). Basta simplemente con identificar los casos e imprimir mensajes utilizando printf indicando el caso correspondiente.
-
Hallar las representaciones binarias en punto flotante de 7 bits con 1 bit de signo, 4 bits de exponente y 4 de parte fraccionaria (seeeeffff) y luego sus valores numéricos en base 10.
- Denormalizado menor
- Normalizado mayor
- NaN
- Infinito positivo
- Cero negativo
-
Convertir los siguientes valores numéricos a su representación en punto flotante de 7 bits con 1 bit de signo, 3 bits de exponente y 3 de parte fraccionaria (seeefff).
- 15.0
- NaN
- -4.25
- -0.125
- 6.75
- 0.0
- 1.0
- -∞
- 14.4
Hint: identificar primero e, E, 2^E, bias, f, M y verificar cumplimiento de v = (-1)^s * M * 2^E.
-
Resolver a qué evalúan las siguientes expresiones de C y justificar por qué. Los valores de las variables x, f y d son arbitrarios y sus tipos son respectivamente int, float y double. Además, f y d no pueden ser +∞, −∞ ni NaN.
f == -(-f)x == (short) (float) x(d + f) - d == ff == (float) (double) f3.0/5.0 == 3/5.0d > f ⇒ -f > -dd == (double) (float) d;
Hint: escribir un programa en C que compruebe los resultados.