lOMoARcPSD|6185940 Examen Febrero 2020, respuestas Fundamentos de Informática (Universidad de Valladolid) StuDocu is not sponsored or endorsed by any college or university Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 SOLUCIÓN Escuela de Ingenierías Industriales Fundamentos de Informática Apellidos (en Mayúsculas) Examen Extraordinario: 3 de febrero de 2020 Nombre Grupo T IM IOI IQ ITI IEIA IE 1 2 3 Observaciones: • • Nota: Rellena los datos (apellidos, nombre y grupo) que se solicitan en la parte superior de esta hoja. Contesta a la cuestión en esta misma hoja. Cuestión C1 (1.4 Puntos) 1. Se quiere conocer las posiciones que ocupan los valores negativos de un vector de enteros. Para ello se pide declarar y definir dos versiones de funciones que realicen esa labor empleando dos prototipos distintos. Completar la declaración, la llamada y la definición en ambos casos. (0.8 Puntos) Declaración versión 1 vector<int> extrae_pos_v1(const vector<int>& ); Llamada versión 1 int main() { vector<int> v= {-1,3,5,-2,-6,8,-7}; vector<int> pos; pos=extrae_pos_v1(v);_ } Definición versión 1 vector<int> extrae_pos_v1(const vector<int>& v) { vector<int> w; for(size_t i=0; i<v.size();i++) { if(v.at(i)<0) w.push_back(i); } return w; } Declaración versión 2 void extrae_pos_v2( const vector<int>&, vector<int>& ); Llamada versión 2 int main() { vector<int> v= {-1,3,5,-2,-6,8,-7}; vector<int> pos; extrae_pos_v2(v,pos); } Definición versión 2 void extrae_pos_v2(const vector<int>& v, vector<int> pos) { pos.clear(); for(size_t i=0; i<v.size();i++) { if(v.at(i)<0) pos.push_back(i); } } Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 2. En una serie aritmética en la que a0 es el primer valor y d la diferencia, el término an es: an = a0 + n*d. (0.6 Puntos) Los valores a0, d y n son números enteros. Para trabajar con series de este tipo se pide la definición de las siguientes funciones (no es necesario realizar la función main() ni la llamada a las mismas). Todas ellas tienen como argumentos a0, d y n. // Calcula los n primeros valores de una serie y los muestra por pantalla void funcion1(int a0,int d,int n) { for(int i=0; i<n; i++) cout<<a0+i*d<<endl; } // Calcula los n primeros valores de una serie, los suma y // devuelve el valor de dicha suma int funcion2(int a0,int d,int n) { int suma=0; for(int i=0; i<n; i++) suma+=a0+i*d; return suma; } // Calcula los n primeros valores de una serie, los almacena en un vector // y devuelve dicho vector vector<int> funcion3(int a0,int d,int n) { vector<int> v; int aux; for(int i=0; i<n; i++) { aux=a0+i*d; v.push_back(aux); } return v; } // Calcula los n primeros valores de una serie almacenándolos en un vector // usando la función anterior, funcion3(). Con este vector calcula la media // aritmética y la devuelve. double funcion4(int a0,int d,int n) { vector<int> v = funcion3(a0,d,n); double suma=0; for(size_t i=0; i<v.size(); i++) suma+=v.at(i); return (suma/n); } Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 Cuestión C2 (1 Punto) Realizar una función con prototipo ¿? operacion(¿? x, ¿? y, ¿? f) que tiene como argumentos de entrada dos vectores x e y y el resultado de una operación a partir de éstos que será introducido en el vector f (ver ecuación). Los vectores son de tipo double. Notad que cada elemento i del vector f debe ser obtenido de las operaciones entre los elementos i de los vectores x e y. La función devuelve una variable lógica con valor verdadero si la dimensión de los vectores x e y coincide y falso si no lo es. 𝑓𝑓𝑖𝑖 (𝑥𝑥𝑖𝑖 , 𝑦𝑦𝑖𝑖 ) = (𝑥𝑥𝑖𝑖 + 2𝑦𝑦𝑖𝑖 − 7)2 + (2𝑥𝑥𝑖𝑖 + 𝑦𝑦𝑖𝑖 − 5)2 , i ∈ [1, … , 𝑛𝑛] bool operacion(const vector<double>& x, const vector<double>& y, vector<double>& f) { double oper1, oper2; if (y.size()!=x.size()) return false; f.clear(); for (int i=0; i<y.size(); i++) { oper1= x.at(i)+2*y.at(i)-7; oper2= 2*x.at(i)+ y.at(i)-5; f.push_back(oper1*oper1+ oper2*oper2); } return true; } Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 Cuestión C3 (1 Punto) En ocasiones las matrices se almacenan en los programas en forma de vectores, aunque se piden y muestran al usuario como matrices. Así, por ejemplo, los elementos de una matriz 3 x 2: 𝑎𝑎00 𝑎𝑎01 �𝑎𝑎10 𝑎𝑎11 � 𝑎𝑎20 𝑎𝑎21 se almacenarían en posiciones sucesivas de un vector, en este caso de tamaño 6, en la forma siguiente: {𝑎𝑎00 , 𝑎𝑎01 , 𝑎𝑎10 , 𝑎𝑎11 , 𝑎𝑎20 , 𝑎𝑎21 } Con esto, el elemento 𝑎𝑎𝑖𝑖𝑖𝑖 de la matriz (fila i, columna j) quedará almacenado en la posición i*col+j del vector, siendo col el número de columnas de la matriz. El siguiente programa ilustra esto. Pide al usuario los elementos 𝑎𝑎𝑖𝑖𝑖𝑖 de una matriz cuadrada N x N y los almacena en posiciones sucesivas de un vector. A continuación, calcula la traza de la matriz (la suma de los elementos de la diagonal principal) y la matriz traspuesta, y muestra los resultados en forma adecuada. Completa el código en las cajas rectangulares correspondientes al cálculo de la traza y de la traspuesta. #include <iostream> #include <vector> using namespace std; int main() { int tam; cout<<"Tamano de la matriz: "; cin>>tam; //Recorre filas y columnas, pide los a_ij y los almacena en posiciones sucesivas // del vector 'm' vector<double> m; for(int i=0; i<tam; ++i) //Recorre las filas { for(int j=0; j<tam; ++j) //Para cada fila, recorre las columnas { cout<<"Introduce a["<<i<<"]["<<j<<"] = "; double valor; cin>>valor; m.push_back(valor); } } // Continúa el código a la vuelta Continúa a la vuelta… Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 // Recorre filas y columnas y almacena en una variable traza (que debes declarar // convenientemente) el valor correspondiente de la matriz original m double traza=0.; for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { if(i==j) double traza=0.; { for(int i=0; i<tam; i++) traza += m.at(i*N+j); { }for(int j=0; j<tam; j++) } { } if(i==j) { traza += m.at(i*tam+j); } } } // Recorre filas y columnas y almacena en un vector m_traspuesta (que debes // declarar convenientemente) los valores de la matriz traspuesta, siguiendo la // misma pauta de guardar el elemento (i,j) de la matriz en la posición j+i*col vector<double> m_traspuesta; for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { m_traspuesta.push_back(m.at(j*N+i)); } } vector<double> m_traspuesta; for(int i=0; i<tam; i++) { for(int j=0; j<tam; j++) { m_traspuesta.push_back(m.at(j*tam+i)); } } //Muestra la traza y la matriz transpuesta cout<<"\n"<<"Traza: "<<traza<<endl; cout<<"\nMatriz traspuesta:"<<endl; for(int k=0, i=0; i<tam; i++) { for(int j=0; j<tam; j++) { cout<<m_traspuesta.at(k++)<<" "; } cout<<endl; } } Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 Cuestión C4 (1.5 puntos) 1. Se pide justificar los diferentes valores obtenidos tras ejecutar el siguiente código. (0.8 puntos) int main() Recordad que tanto la representación interna de números enteros como la de nú{ meros reales (precisión simple) utiliza 32 bits. int n=16; float x=16; Al ejecutar el código mostrado se ha obtenido este resultado: int z=-3; n=16 for(int i=0; i<4; i++) x=16 { n=256 cout<<"n="<<n<<endl; x=256 n*=n; n=65536 cout<<"x="<<x<<endl; x=65536 x*=x; z=z*(i+1); n=0 } x=4.29497e+009 } a) Justificar el último valor obtenido para n. El rango de representación de números enteros en complemento a 2 con 32 bits es: [-232-1 232-1-1] En el código, el primer valor de n es 16=24, de modo que el último valor calculado para n (cuando i=3) corresponde a n=232. La representación interna correcta de este valor supone el uso de 33 bits (1 seguido de 32 ceros): 1000 … 000 32 bits Pero al disponer solamente de 32 bits para la asignación de memoria para n, quedarían almacenados justo los 32 “ceros” y de ahí el resultado. b) Obtener la representación binaria del último valor obtenido de x. Mostrad el proceso de obtención. Los números reales (racionales) se representan en el formato coma flotante (Estándar IEEE 754). En el caso de simple precisión tendríamos para 𝑥𝑥 = 232 = 1.0 × 232 la siguiente representación (teniendo en cuenta el exponente e en exceso 127: e=32+127=159): signo 01001111100000000000000000000000 exponente mantisa c) ¿Justificar cuál sería la cantidad mínima de bits necesarios para representar de forma correcta el valor final de z? Después de la ejecución z=-72. Teniendo en cuenta el rango de representación en complemento a 2 empleando n bits: [-2n-1 2n-1-1], resulta que el n mínimo sería 8 (para n=7, el número más pequeño que se podría representar sería -26=-64). d) ¿Justificar cuál sería la representación en complemento a 2 de z con ese número mínimo de bits? El número positivo 72 tiene su equivalente binario (con 8 bits): 01001000, de modo que el -72 sería (representación en complemento a 2): 10111000. Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 2. Este año se conmemora el centenario de la muerte de Benito Pérez Galdós y por esta razón se quiere codificar en binario todas las novelas que forman la colección “Episodios Nacionales” de las que sabemos que: (0.7 puntos) • Hay un total de 46 novelas. • El total de 46 novelas se organizan en 5 series: las cuatro primeras de 10 volúmenes cada una y la última de 6. Se plantean dos opciones de codificación, que llamaremos COD1 y COD2: - Codificación COD1: o Usa un número para el ordinal de cada una de las 46 novelas (1, 2, …, 46). o El aspecto de la codificación binaria será x1…xn, donde los xi son 0 o 1. - Codificación COD2: o Usa un número para la serie (1, 2, 3, 4, 5), otro para el volumen dentro de cada serie (1, 2, …,10). o El aspecto de la codificación binaria será x1…xpy1…yr, donde los xi y yj son 0 o 1. Se pide, para cada código: a) Si se trabaja en binario, indicar el número mínimo de bits para cada uno de los campos. b) Cuantos libros sería posible codificar con cada uno de ellos si se empleará este código con número mínimo de bits para colecciones con estructura similar (un número L de libros organizados en S series). c) Indicar cuál sería la codificación en cada caso “Narváez”, número 32, segundo de la cuarta serie. COD1 a) Para referenciar los 46 libros (se pueden numerar desde el 0 hasta el 45 o desde el 1 hasta el 46) se necesitan 6 bits (25=32 < 46 < 26=64). Un total de 6 bits. b) 26 libros c) Número 32 con 6 bits: Codificación: 100000 (empezando en 1) 100000 COD2 a) Para identificar las 5 series (se pueden numerar desde 0 hasta 4 o desde 1 hasta 5), son necesarios 3 bits (22=4 < 6 < 23=8). Para cada volumen dentro de la serie (hay máximo 10 volúmenes en cada una) son suficientes 4 bits (23=8 < 10 < 24=16 Un total de 3 + 4 = 7 bits. b) 23 series, 24 libros. Hay 27 posibilidades. c) Serie 4 con 3 bits: Volumen 2 con 4 bits: Codificación: 100 (empezando en 1) 0010 (empezando en 1) 1000010 COD1 y COD2 d) A la vista de las respuestas ¿cuáles pueden ser las ventajas o inconvenientes de cada código? El segundo código permite codificar más libros (el doble). Sin embargo, si una serie tiene más de 16 libros no puede codificarse. . Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 Cuestión C5 (1.6 Puntos) (0.25 puntos) 1) Diferencias entre compilador e intérprete. Compilador genera código binario tras un análisis global del programa en código fuente. El intérprete solo realiza la traducción del programa fuente a medida que es necesario. Compilador equivale a traductor profesional de un texto que genera otro texto en otra lengua, mientras que el intérprete se corresponde con el intérprete humano que va traduciendo oralmente las palabras que oye, sin dejar constancia por escrito. … 2) Diferencias entre memoria RAM y ROM. (0.25 puntos) RAM es la memoria dinámica, memoria física direccionable en la arquitectura Von Newman, necesita alimentación eléctrica durante la sesión o ejecución de programas… ROM no necesita de alimentación eléctrica, almacenamiento permanente entre sesiones. 3) Se muestran dos opciones para cargar valores de una matriz en forma vector. (0.25 puntos) En el contexto de la jerarquía de memoria: a) ¿qué concepto interviene para preferir una opción sobre otra?, b) ¿cuál sería la más correcta y por qué? vector<double> m(tam*tam); for(int i=0; i<tam; ++i) for(int j=0; j<tam; ++j) { cout<<"m["<<i<<"]["<<j<<"] = "; cin>>m[i*tam+j]; } vector<double> m(tam*tam); for(int j=0; j<tam; ++j) for(int i=0; i<tam; ++i) { cout<<"m["<<i<<"]["<<j<<"] = "; cin>>m[i*tam+j]; } Basándose en el concepto de localidad espacial, la primera versión es más correcta porque se asignan direcciones contiguas (en la medida de lo posible) a los elementos de la matriz dentro de cada fila. El bucle for externo de la primera versión permite ir tomando elementos de cada fila, mientras que el de la segunda versión los toma por columnas, obligando a dar continuos saltos a direcciones de memoria no consecutivas… Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com) lOMoARcPSD|6185940 4) Poner nombres a los registros (bloques en blanco) en el esquema siguiente de una arquitectura tipo acumulador y completar en la tabla las palabras que forman el acrónimo (véase ejemplo): (0.3 puntos) CPU Central processing unit Pág. 47 y siguientes, T5 (Registros PC, SP, IR, AC, CU, MAR, MBR). 5) Cuáles son los tres elementos básicos en arquitectura de ordenadores, y los tres mecanismos de abstracción correspondientes en sistemas operativos, estableciendo sus relaciones e inclusiones. (0.25 puntos) Elementos en arquitectura: CPU, memoria principal, Dispositivos de E/S. Mecanismos de abstracción en sistemas operativos: - Ficheros, abstracción de los dispositivos de E/S. - Memoria virtual, abstracción de los dispositivos de E/S y memoria principal. - Procesos, abstracción de los dispositivos de E/S, memoria principal y CPU. 6) Calcular el número decimal cuya representación en coma flotante de 16 bits (1 de signo, 8 de exponente (exceso 127) y 7 de mantisa, inspirada en la IEEE 754), compactada en hexadecimal, es C1FD. (0.3 puntos) En decimal: Nbin = 1100 0001 1111 1101 msb: Signo 1, negativo Exponente: 1000 0011 => 27 + 2 + 1 = 128+2+1 = 131 131 – (Exceso 127) = 4 Mantisa:(Uno implícito).1111 101 =>1*20 +1*2−1 +1*2−2 +1*2−3 +1*2−4 +1*2−5 +1*2−7 = 1,9765625 Ndec = -1,9765625 * 24 = -1,9765625 * 16 = -31,625 Universidad de Valladolid – Departamento de Ingeniería de Sistemas y Automática Downloaded by Guillermo Gargga (wigarga@gmail.com)