Skip to content

Latest commit

 

History

History
374 lines (319 loc) · 11.7 KB

File metadata and controls

374 lines (319 loc) · 11.7 KB

01 - Representación de datos

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.

  1. Convertir los siguientes números en representación decimal a binario (16bits)

    1. 18265
    2. 7810
    3. 51007
    4. 66425
    5. 31530
    6. 19725
    7. 5736
    8. 423
  2. 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;
    }
  3. Convertir los siguientes números en representación hexadecimal a binario (16bits)

    1. 0xdc2d
    2. 0x9b7a
    3. 0xfdd8
    4. 0xe882
    5. 0xe8b2
    6. 0x6e49
    7. 0x235e
    8. 0x3343
    9. 0x39d1
    10. 0xf093
  4. 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.

  5. Convertir los siguientes números en representación binaria a hexadecimal (16bits)

    1. 0b0100000110101101
    2. 0b0101100011001010
    3. 0b0001001001101110
    4. 0b1001010000100101
    5. 0b1000001101010110
    6. 0b1101010101101110
    7. 0b1010010001101110
    8. 0b0100100101011100
    9. 0b1011100110011010
    10. 0b0100010011011101
  6. 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.

  7. 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.

  8. 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

  9. Escribir un programa en C que muestre el endianness de la plataforma en la que se ejecuta el programa.

    Hint: read the book

  10. 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

  11. Resolver los siguientes problemas de álgebra booleana.

    1. (~A) para:
      1. A = 0xac
      2. A = 0x11
      3. A = 0x23
      4. A = 0xde
    2. (A | B) para:
      1. A = 0xac ; B = 0x32
      2. A = 0x11 ; B = 0xaa
      3. A = 0x23 ; B = 0xff
      4. A = 0xde ; B = 0x13
    3. (A & B) para:
      1. A = 0xac ; B = 0x32
      2. A = 0x11 ; B = 0xaa
      3. A = 0x23 ; B = 0xff
      4. A = 0xde ; B = 0x13
    4. (A ^ B) para:
      1. A = 0xac ; B = 0x32
      2. A = 0x11 ; B = 0xaa
      3. A = 0x23 ; B = 0xff
      4. A = 0xde ; B = 0x13
  12. 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.

  13. Resolver los siguientes problemas de manejo de bits.

    1. (0xffe2 >> 3)
    2. (0xace2 << 5)
    3. (0x12e2 >> 2)
    4. (0xf1eb >> 1)
    5. (0xab12 << 6)
    6. (0x62ea >> 2)
  14. 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);
  15. Escribir en representación entera de 16bits con complemento a dos los siguientes números.

    1. 14772
    2. 12110
    3. -13483
    4. -8104
    5. 11518
    6. -29641
    7. -3188
    8. -19378
    9. 8566
    10. -4682
  16. 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.

    1. 0b1111000010010011
    2. 0b0011110100011101
    3. 0b1010011011010111
    4. 0b0110101001010111
    5. 0b1111001101000001
    6. 0b0100110000011011
    7. 0b1111001101001000
    8. 0b0110001100000011
    9. 0b1011101001101011
    10. 0b0100111110011011
  17. 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.

    1. 53888
    2. 47428
    3. 36650
    4. 1455
    5. 29128
    6. 36040
    7. 65536
    8. 52854
    9. 29626
    10. 46818
  18. 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.

    1. -2147483647-1 == 2147483648U
    2. -2147483647-1 < 2147483647
    3. -2147483647-1U < 2147483647
    4. -2147483647-1 < -2147483647
    5. -2147483647-1U < -2147483647
    6. 2147483647U > -2147483647-1
    7. 2147483647 > (int) 2147483648U
    8. -1 < 0U

    Hint: escribir un programa en C que compruebe los resultados.

  19. 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

    1. 13528
    2. -11674
    3. 27091
    4. -15913
    5. 22782
    6. -8521
    7. 4874
    8. -698
    9. 13992
    10. 17396
  20. 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

    1. -1580948425
    2. 1870865340
    3. -107982815
    4. -157511958
    5. 742922907
    6. -1163069406
    7. 1813815629
    8. 223375263
    9. -625813639
    10. 403361717
  21. 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.

    1. 888678457
    2. 2851757120
    3. 1912450232
    4. 4079538690
    5. 4154371837
    6. 1988670315
    7. 442559150
    8. 2595390421
    9. 2860812492
    10. 515237114
  22. 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.

    1. 9837
    2. 18328
    3. 30932
    4. -26481
    5. -24356
    6. 2260
    7. 25312
    8. -31865
    9. 4919
    10. -336
  23. 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.

  24. 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:
      1. ~a (complemento a uno)
      2. a
      3. a * 7
      4. (a < 0) ? 1 : -1
    • Expresiones:
      1. ~(~a | (b ^ (INT_MIN + INT_MAX)))
      2. ((a ^ b) & ~b) | (~(a ^ b) & b)
      3. 1 + (a << 3) + ~a
      4. (a << 4) + (a << 2) + (a << 1)
      5. ((a < 0) ? (a + 3) : a) >> 2
      6. a ^ (INT_MIN + INT_MAX)
      7. ~((a | (~a + 1)) >> W) & 1
      8. ~((a >> W) << 1)
      9. a >> 2
  25. 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. 1.125
    2. 0.6723
    3. 0.98911
    4. 0.25
    5. 0.8984
    6. 0.743
    7. 1.832
    8. 0.902
    9. 0.12300
    10. 1.1111
  26. Convertir los siguientes números representados en punto fijo a decimal.

    1. 11.101110
    2. 1101.1111
    3. 0110.1101
    4. 010000.01
    5. 100.10100
    6. 10.101010
    7. 1.1011100
    8. 10001.111
    9. 0.1110010
    10. 1.1000010
  27. 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.

    1. 0b1111101
    2. 0b0110101
    3. 0b0000110
    4. 0b1110000
    5. 0b1100100

    Hint: identificar primero a qué caso de representación de punto flotante simil IEEE representan (valores normalizados, denormalizados, especiales).

  28. 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.

  29. 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.

    1. Denormalizado menor
    2. Normalizado mayor
    3. NaN
    4. Infinito positivo
    5. Cero negativo
  30. 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).

    1. 15.0
    2. NaN
    3. -4.25
    4. -0.125
    5. 6.75
    6. 0.0
    7. 1.0
    8. -∞
    9. 14.4

    Hint: identificar primero e, E, 2^E, bias, f, M y verificar cumplimiento de v = (-1)^s * M * 2^E.

  31. 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.

    1. f == -(-f)
    2. x == (short) (float) x
    3. (d + f) - d == f
    4. f == (float) (double) f
    5. 3.0/5.0 == 3/5.0
    6. d > f ⇒ -f > -d
    7. d == (double) (float) d;

    Hint: escribir un programa en C que compruebe los resultados.