elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 9 10 11 12 [13] 14 15 16 17 18 19 20 21 22 23 24 25 26
121  Programación / Programación C/C++ / Re: Operadores a nivel de bits (lenguaje C). en: 21 Marzo 2014, 15:16 pm
Correcto!
122  Programación / Programación C/C++ / Re: Problema con errorC2296 en C++ en: 21 Marzo 2014, 15:11 pm
De acuerdo con amchacón, es más fácil:
Código
  1. for(i=1; i<=n; i++){
  2.    if ( i % 2 )       /* i impar */
  3.        pi = pi - 1/(2*i+1);
  4.    else               /* i par */
  5.        pi = pi + 1/(2*i+1);
  6.   }
  7.  
donde por cierto debe ser "i <= n", no "i == n". Esta solución es preferible por cuanto se debe procurar el código que implique menos esfuerzo de cálculo: con esa sentencia evitas invocar la operación de potenciación. Además hay que tener cuidado con la exponenciación de números de base negativa, recuerda que si los parámetros no son adecuados pudiera resultar en un número con una parte imaginaria.

123  Programación / Programación C/C++ / Re: Binomio de Newton, y triángulo de Pascal en: 21 Marzo 2014, 14:54 pm
Leosansan:

1. Recuerda que el tema en realidad lo abrí yo, y puse la descripción del mismo. Ahora quieres cambiarme el problema, y encima reprochas a los demás y a mí porque el problema no se conduce como TÚ quieres. Te recomiendo dos cosas: (a) Ve al psicólogo. (b) Abre tu propio tema..

2. Recursión, recurrencia o recursividad se pueden considerar palabras de significados similares. No hay por qué hacer tanto escándalo (a no ser con el objeto de descalificar a los demás). La fuente http://es.wikipedia.org/wiki/Recursi%C3%B3n aclara:
Citar
Recurrencia, recursión o recursividad es la forma en la cual se especifica un proceso basado en su propia definición. Siendo un poco más precisos, y para evitar el aparente círculo sin fin en esta definición:
Un problema que pueda ser definido en función de su tamaño, sea este N, pueda ser dividido en instancias más pequeñas (< N) del mismo problema y se conozca la solución explícita a las instancias más simples, lo que se conoce como casos base, se puede aplicar inducción sobre las llamadas más pequeñas y suponer que estas quedan resueltas.
En otras palabras, la definición para el caso de "N" se basa en la definición para los casos desde "1" hasta "N-1", algunos de los cuales están predefinidos de cierta manera. No obstante, la misma fuente dice que el término correcto en nuestra lengua es "recurrencia".

3. El empleo de la palabra "recursión" viene de boca de amchacón quién dijo: "Que no use recursividad, debe sacar la fila del tirón." Analizando el contexto de sus palabras, más allá de lo linguístico, cualquiera con buena intención puede inferir lo que quiso decir: Que los números de una fila del triángulo no se calculen usando los números de filas anteriores. Lo que traté fue dar respuesta a ese planteamiento, mismo que también fue comprendido por ivance96.

4. Este no es un foro de matemáticas (que quede claro), pero ya mencionas tanto ese tema te pongo de ejercicio investigar las siguientes demostraciones:
(a) El elemento unidad en R es único.
(b) La propiedad anterior es válida para toda ley de composición interna que sea conmutativa.
(c) El límite de una función real de variable real, si existe, es único.
Por lo menos te puedo decir que yo las conozco y te las puedo dar sin siquiera mirar el libro (sin ánimo de ofender, pues es mi profesión y se supone que lo haga, tal como un cirujano debe ser capaz de operar, un aviador de volar, etc., sin ver el manual). ¿Tú puedes responder las mismas preguntas? Si lo haces eres un verdadero matemático, capaz de citar y comprender definiciones, y realizar demostraciones. De otro modo, por favor DEJA la diatriba y comentarios del tipo:
Citar
¡¡¡PERO POR DIOS!!! , en que lugar estas dejando las Matemáticas.
dirigidos hacia mí. Sino deberé presentar una queja a los moderadores del foro.
124  Programación / Programación C/C++ / Re: Binomio de Newton, y triángulo de Pascal en: 20 Marzo 2014, 16:40 pm
Claro ivance, pero lo que el autor del tema quiere decir es calcular los números de una fila del triángulo sin usar los valores de las filas anteriores.
125  Programación / Programación C/C++ / Re: Binomio de Newton, y triángulo de Pascal en: 20 Marzo 2014, 16:19 pm
En informática decimos "recursividad" para referirnos a una función que se llama a sí misma. Pero en el tema de las sucesiones numéricas, la "recursividad" es cuando los términos de la sucesión se generan a partir de los términos anteriores. Por ejemplo la famosa sucesión de Fibonacci a0, a1, a2, ... donde

a0 = 0, a1 = 1

y an = an-1 + an-2 para n>=2 (cada término es la suma de los dos anteriores). Queda entonces:

0,  1,  2,  3,  5,  8,  ...

(ver más en http://es.wikipedia.org/wiki/Sucesi%C3%B3n_de_Fibonacci). Esta es una sucesión por recursividad, mismo método por el que podemos obtener los coeficientes del triangulo de Pascal, pero tenemos prohibido hacerlo por ahí  ;D

Voy con mi propuesta. No se si la intención del problema era usar la clase <vector>, pero yo lo hice en C básico. La fórmula el i-ésimo número en la n-ésima filas del triángulo es:

    n!    
----------
 i! (n-1)!

por lo tanto creé una función que genera los factoriales desde 1! hasta n! (se adopta que 0! = 1 por convencionalismo) en un arreglo de n números del tipo long long. Luego es fácil obtener los binomiales. Queda extenso el código primero porque no se usan plantillas de clase, y segundo porque se verifica la asignación dinámica de memoria:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. long long * factorial( int );
  5. int * FilaTrianguloPascal( int );
  6.  
  7. int main() {
  8.  
  9.   int *fila;
  10.   int i, n;
  11.  
  12.   n = 10;
  13.   if ( ( fila = FilaTrianguloPascal( n ) ) == NULL )
  14.      return -1;
  15.   i = 0;
  16.   while ( i < n + 1 )
  17.      printf( "%d ", fila[i++] );
  18.  
  19.   return 0;
  20. }
  21.  
  22. /* Calcula los valores de la fila n-esima del triangulo de Pascal */
  23. int * FilaTrianguloPascal( int n ) {
  24.  
  25.   int i, * fila;
  26.   long long * fact;
  27.  
  28.   if ( ( fila = (int *) malloc( (n + 1) *sizeof(int) ) ) == NULL )
  29.      return NULL;
  30.   if ( ( fact = factorial( n ) ) == NULL )
  31.      return NULL;
  32.  
  33.   fila[0] = fila[n] = 1;
  34.   for ( i = 1; i < n; i++ )
  35.      /* fact[k-1] contiene k! */
  36.      fila[i] = fact[n - 1]/ fact[i - 1] / fact[n - i - 1];
  37.  
  38.   return fila;
  39. }
  40.  
  41. /* Devuelve en un arreglo de n+1 elementos los números desde
  42.  * 0! hasta n!.
  43.  * Si no pudo asignar memoria para el arreglo, devuelve NULL.
  44.  */
  45. long long * factorial( int n ) {
  46.  
  47.   int i;
  48.   long long * vector;
  49.  
  50.   if ( ( vector = (long long *) malloc( n * sizeof(long long) ) ) == NULL )
  51.      return NULL;
  52.  
  53.   vector[0] = 1;
  54.   for ( i = 1; i < n; i++ )
  55.      /* vector[i] contiene (i+1)! */
  56.      vector[i] = (i + 1) * vector[i-1];
  57.  
  58.   return vector;
  59. }

NOTA: Amchacon, me gustó este reto porque parece ser muy conciso en sus objetivos. Modifiqué el prototipo de FilaTrianguloPascal para que retornara el vector creado en lugar de recibir el puntero por argumento. Al menos si estamos programando en C me parece más lógico este procedimiento porque la función asigna la memoria dinámicamente y posiblemente relocalice el puntero, entonces ¿qué sentido tiene pasar un puntero como argumento para que la función te devuelva otro? En todo caso se puede pasar el puntero por referencia, un doble puntero long long **, ......... pero ya eso es muy complicado puff, preferí que la función devolviera el puntero final de una vez.

====================================
EDITO:

Hay un detalle con el desbordamiento de los números. Me parece que el tipo long long alcanza para almacenar los números de la fila del triángulo, más no los factoriales requeridos como paso intermedio para el cálculo. Modifiqué el main() para que imprimiera los factoriales solamente:
Código
  1.   n = 25;
  2.   long long * v = factorial( n );
  3.   i = -1;
  4.   while ( ++i < n )
  5.      printf("%02d! = % 20lld\n", i+1, v[i]);
  6.   printf("\n");
  7.  
Véase lo que sucede a partir de 21!:

 15! =        1307674368000
 16! =       20922789888000
 17! =      355687428096000
 18! =     6402373705728000
 19! =   121645100408832000
 20! =  2432902008176640000
 21! = -4249290049419214848
 22! = -1250660718674968576
 23! =  8128291617894825984

A mí me parece desbordamiento ... Y es de recordar que los valores de la función factorial creen muy rápido, incluso más rápido que los valores de la función exponencial en.
Cambiemos al tipo unsigned long long, a ver qué pasa. Modificando el prototipo de factorial() y la cadena de formato de printf():

15! =        1307674368000
16! =       20922789888000
17! =      355687428096000
18! =     6402373705728000
19! =   121645100408832000
20! =  2432902008176640000
21! = 14197454024290336768
22! = 17196083355034583040
23! =  8128291617894825984
24! = 10611558092380307456
25! =  7034535277573963776

Pasa algo extraño del 22! al 23!. E incluso si pedimos imprimir los binomiales, da números negtivos:

1 -1 -17 -110 -497 -1692 -4513 -9671 -16924 -24446 -29335 -29335 -24446 -16924 -9671 -4513 -1692 -497 -110 -17 -1 1


¿Qué opinan de ésto?  :huh:
126  Programación / Programación C/C++ / Re: Binomio de Newton, y triángulo de Pascal en: 20 Marzo 2014, 15:43 pm
ivance, te saliste del reto!!! No puedes usar recursividad:

push_back(v[i-1][j]+v[i-1][j-1]);

 :rolleyes:
127  Programación / Programación C/C++ / Re: De minúscula a mayúscula a nivel de bits (lenguaje C.) en: 20 Marzo 2014, 15:22 pm
Por lo visto, restar 32 decimal, o sea 0x20, para pasar del código ASCII de letra mayúscula al de la respectiva minúscula. Para eso anulas el bit 5, que puedes hacer con una máscara. Revisando los códigos ASCII de todos los caracteres en mayúscula, van desde 0x61 hast 0x7A y todos poseen el bit nro. 5 en '1', por lo tanto es válido restar de este modo (hubiera sido un problema si el bit5 fuera '0', pero esto no sucede).
128  Programación / Programación C/C++ / Re: problema con el game en dev c++ en: 20 Marzo 2014, 15:13 pm
Ah, .... y debe ser "explosion", no "explocion". Se que es una nimiedad, pero nunca está demás  ;)
129  Programación / Programación C/C++ / Re: Operadores a nivel de bits (lenguaje C). en: 20 Marzo 2014, 15:10 pm
Para abreviarte un poco el trabajo, lo que rir3760 es un doble "for" anidado para imprimir el número en grupos de a 8 bits (o sea, bytes), con un espacio entre cada byte, e.g.:

11000001 00010011 10100110 00010111

El for con el contador "j" imprime cada octeto y el for con el contador "i" pasa de un octeto a otro. Mira que la instrucción sizeof(unsigned) te da el tamaño de un unsigned (que es el mismo tamaño del int) en bytes, que es 4 para el caso de una máquina con enteros de 32 bits. Este es el rango de i. Luego, la macro CHAR_BIT da el número de bits que ocupa un byte, o sea 8 en nuestro caso. Este es el rango de j.

De no haber usado este anidamiento el número se hubiera impreso con todos los bits "pegados", o sea, menos estéticamente. Otra solución, con un solo contador, tal vez hubiera sido intercalar un espacio luego del bit 7, luego del bit, 15, y luego del 23, con el operador módulo "%". Si el número más 1 es divisible por 8, dejar el espacio:
Código
  1. void imprimir(unsigned num)
  2. {
  3.  unsigned msb = 1U << sizeof(unsigned) * CHAR_BIT - 1;
  4.  size_t i;
  5.  size_t j;
  6.  
  7.  for (i = 0; i < sizeof(unsigned) * CHAR_BIT; i++){
  8.     putchar(num & msb ? '1' : '0');
  9.     msb >>= 1;
  10.  
  11.     /* aqui el espacio */
  12.     if ( i > 0 && (i + 1)%8 == 0 )
  13.        putchar(' ');
  14.  }
  15.  putchar('\n');
  16. }
  17.  
donde la condición i > 0 es para que no imprima espacio antes del bit número cero (el primero).

Por último, el tipo size_t es un tipo aritmético, normalmente un entero no signado, devuelto por el operador sizeof() y usado en funciones como strlen(), fread(), etc. Para decirlo de un modo sencillo, usamos ese tipo para enumerar cantidades "posiblemente grandes" de bytes. En el caso de rir3760 se definió "i" de tipo size_t porque ese es el tipo devuelto por la expresión sizeof(unsigned).

Se que dijiste que ibas a investigar todo esto, y deseo que lo hagas pero no me costaba nada dedicar 5 minutos a aclarar unas cosas que te hubieran demandado quiźa 2 horas (y así usas esas 2 horas en investigar otros temas  ;D).
130  Programación / Programación C/C++ / Re: Operadores a nivel de bits (lenguaje C). en: 18 Marzo 2014, 22:14 pm
Ok, creo NOMB2014 que la intención de la "máscara" en los programas anteriores era imprimir un número en binario (por eso putchar() que imprime carácter a carácter). Para que la explicación sea más sencill pondré un ejemplo con un char (un byte).

Si queremos imprimir en binario tenemos que escanear cada uno de sus bits e imprimir un '1' ó un '0' según el caso. Pongamos el ejemplo del numero:

num = 1000 1001

Entonces comenzamos con la máscara mask = 1000 0000 (0x80 en hexadecimal). Hacemos el AND binario entre el número y la máscara. Observa bien que la máscara tendrá un único bit en 1, los demás en 0. Si el AND binario da como resultado distinto de cero es porque el número original posee un '1' en la misma posición de la máscara. Así que el bit más significativo del número es '1':

num & mask = 1000 1001 & 1000 0000 = 1000 0000

Ahora seguimos recorriendo el número de izquierda a derecha, para ellos usamos la máscara mask = 0100 0000 (0x40 en hexadecimal). El resultado será '0', porque el número posee un bit '0' en la misma posición donde la máscara tiene su único 'bit 1':

num & mask = 1000 1001 & 0100 0010 = 0000 0000

Y así ya conoces el valor de los dos bits más significativos de num. Siguiendo con las máscaras 0010 0000,  0001 0000, etc., conocerás los demás bits.

Observa que las máscaras sucesivas se obtienen fácilmente empezando con 1000 0000 y rotando a la derecha tantas veces como uno menos que la cantidad total de dígitos binarios que posea el número.

Así, un programa para imprimir en binario un número char sería, donde por sencillez sustituyo el operador ternario "?:" por un "if" estándar:
Código
  1. void imprimir(unsigned char num)
  2. {
  3. unsigned char mask = 0x80; /* la mascara */
  4. size_t i;
  5.  
  6. for (i = 0; i < sizeof(char) * CHAR_BIT; i++) {
  7. if ( num & mask )
  8. putchar('1');
  9. else
  10. putchar('0');
  11. mask >>= 1;
  12. }
  13. }
  14.  

=============
OBSERVACIONES: 1. Una forma de inicializar la máscara hubiera sido mask = 0x01 << 7, o sea agarrar el 0x01 y rodar el '1' a la izquierda 7 veces. O más consistentemente, mask = 1 << sizeof(char) * CHAR_BIT - 1. Digo que la segunda forma es más consistente, porque se puede cambiar fácilmente el tipo char por short int, o por int donde el tamaño del número en bits es determinado automáticamente por el compilador en lugar de hacerlo nosotros manualmente.

2. El importante el tipo de la máscara como "unsigned". Pues según las especificaciones para enteros signados negativos el comportamiento de la operación ">>" queda indeterminado. Los bits desplazados en la parte izquierda del número pudieran ser rellenados por '1', o por '0' dependiendo del sistema.
Páginas: 1 2 3 4 5 6 7 8 9 10 11 12 [13] 14 15 16 17 18 19 20 21 22 23 24 25 26
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines