Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: Feynmann en 21 Marzo 2014, 12:54 PM

Título: Problema con errorC2296 en C++
Publicado por: Feynmann en 21 Marzo 2014, 12:54 PM
Buenos dias,

Tengo el siguiente programa:


#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

int main ()
{
   double pi=1.0;
   int n,i,r ;
   cin >> n;
   for(i=1; i==n; i++){
      pi=pi + (-1)^i/(2*i+1) ;
   }
   cout << pi;
   system("PAUSE");
   return 0;
}


error C2296: '^' : no es válido; el operando izquierdo es de tipo 'double'   


¿como puedo resolver este error, y por que se da?


Muchas Gracias de antemano.
Título: Re: Problema con errorC2296 en C++
Publicado por: amchacon en 21 Marzo 2014, 13:18 PM
No existe el operador ^ en C.

Para las potencias hay que usar la función pow (base,exponente)

Aunque en este caso no la necesitas, va a dar 1 si i es par y -1 si es impar.
Título: Re: Problema con errorC2296 en C++
Publicado por: Yoel Alejandro en 21 Marzo 2014, 15:11 PM
De acuerdo con amchacón, es más fácil:
Código (cpp) [Seleccionar]

for(i=1; i<=n; i++){
    if ( i % 2 )       /* i impar */
        pi = pi - 1/(2*i+1);
    else               /* i par */
        pi = pi + 1/(2*i+1);
   }

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.

Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 21 Marzo 2014, 15:28 PM
Ostras,
Estoy acostumbrado a usar programas de lenguaje simbolico como mathematica y de ahi el ^.
Por otro lado tiene bastante logica todo lo que comentas yoel. Muchas gracias a los dos.

Ultima pregunta: Para aprender me estoy haciendo los ejercicios de problemas resueltos de C++, y ojeandome poco a poco mis dudas por internet. No voy a la universidad y no puedo pagarme clases y no sé si es el mejor metodo para aprender, me aconsejais alguna otra cosa?


Un saludo.
Título: Re: Problema con errorC2296 en C++
Publicado por: dato000 en 21 Marzo 2014, 15:37 PM
No entendi muy lo que quieres hacer pero aquí va algo:

Código (cpp) [Seleccionar]

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

int main ()
{
   double pi=1.0;
   int n,i,r ;
   cout << "Digite n:"; cin >> n;
   for(i=0; i<n; i++){ // lo mejor es inicializar el indice en cero
      //pi=pi + (-1)^i/(2*i+1) ;

      pi += pi +( pow(-1, i+1)/(2*i+1));
   }
   cout << pi;
   getchar();
   return 0;
}

Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 21 Marzo 2014, 15:49 PM
Dato000, es un pequeño programa para calcular por aproximación el número pi.

Veo que al final del programa has usado

getchar();


He buscado , pero no acabo de entender para que sirve, por que lo pones?
"La función getchar retorna el carácter siguiente desde el stream de entrada apuntado por stream. Si el stream está en el final de fichero, el indicador del final de fichero para el stream es activado y getchar retorna EOF. Si ocurre un error de lectura, el indicador de error para el stream es activado y getchar retorna EOF."
Título: Re: Problema con errorC2296 en C++
Publicado por: dato000 en 21 Marzo 2014, 16:26 PM
No claro claro, entiendo lo del uso del pi, lo que no se es que tipo de operación necesitas ejecutar para el cálculo. Es obtener PI pero no se como es la ecuación.

getchar es como un System("PAUSE") sin el System("PAUSE"), ejecuta una sentencia en la que espera que el usuario digite una tecla para avanzar con el programa. El problema de usar un llamado al sistema es bueno, por costumbre o tradición no deberia hacerse eso, es como una mala practica, las razones y demás, pues te dirán que es por memoria o saturación y eso, pero para este tipo de ejercicios, es simplemente adquirir buenas bases, y usar sentencias que llaman al sistema directamente es bueno, algo incorrecto.
Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 21 Marzo 2014, 16:32 PM
Me ha quedado clarísimo lo del getchar();, Genial.

Respecto a tu pregunta, la expresion que te da el numero Pi por aproximación es la siguiente:

Pi/4= 1-(1/3)+(1/5)-(1/7)+(1/9)- ... = Sumatorio (de 0 a n)[(-1)^n/(2n+1)]

Gracias dato000 ;)

Título: Re: Problema con errorC2296 en C++
Publicado por: dato000 en 21 Marzo 2014, 16:54 PM
En ese caso seria algo así, no se si son correctos los valores, pero viendo la función mátematica sería algo así:

Código (cpp) [Seleccionar]
for(i=0; i<=n; i++)  // lo mejor es inicializar el indice en cero
{
      //pi=pi + (-1)^i/(2*i+1) ;

      pi = pi + ( pow(-1, i) / ( 2*(i+1) ) );
      //tambien funciona con pi += ( pow(-1, i) / ( 2*(i+1) ) );
}
Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 22 Marzo 2014, 18:12 PM
Perfecto, todo entendido.
Muchas gracias!  :D
Título: Re: Problema con errorC2296 en C++
Publicado por: amchacon en 22 Marzo 2014, 19:08 PM
No recomiendo para nada usar pow aquí, es muy mala práctica ya que pow es una función relativamente costosa y aquí no la necesitas.

La solución que propone yoel_alejrando soluciona el problema. Aunque yo opto por esta otra, más corta, más concisa, sin comparaciones y sin copypastear líneas:

Código (cpp) [Seleccionar]
int signo[2] = {1,-1};
for(i=1; i<=n; i++)
  pi = pi - signo[i%2]/(2*i+1);
Título: Re: Problema con errorC2296 en C++
Publicado por: leosansan en 22 Marzo 2014, 20:40 PM
Cita de: amchacon en 22 Marzo 2014, 19:08 PM
No recomiendo para nada usar pow aquí, es muy mala práctica ya que pow es una función relativamente costosa y aquí no la necesitas.
....................................

Totalmente de acuerdo.

Antes que nada, le sobraban dos librerías,  <fstream>, <string> y le habría faltado tal como lo tenía  <cstdlib> para el system. Ahora con getchar faltaría <cstdio> y sin pow sobraría <cmath>.

Me apunto al no uso de pow y, como simple variante al método de amchacon, ya que creo que "*" es menos costosa como operación que "%":


Código (cpp) [Seleccionar]
#include <iostream>
#include <cstdio>

using namespace std;

int main () {
  double pi,serie=0.0;
  int n,i,mas_menos=1 ;
  cout << "Entre el numero de terminos a tomar: ";
  cin >> n;
  for(i=0; i< n; i++){
     serie+=(1./(2*i+1))*mas_menos;
     mas_menos*=-1;
  }
  pi=4*serie;
  cout << pi<< endl;
  getchar();
  return 0;
}


Yen mi código es" i<", no" i<=" ya que en dicho caso tomaría un sumando de más.

Observar el 1. en 1./(2*i+1) ya que de poner sólo 1/(2*i+1) la operación sería entre enteros y no daría el resultado esperado de double.

Y Feynmann para cuando cuelgues  código elige las etiquetas GeSHi y toma la C++ y en medio de las etiquetas Code que aparecen "pegas" tu código. Al no hacerlo de esta manera parte del código no sale correcta, especialmente las matrices.
Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 23 Marzo 2014, 15:56 PM

Me ha molado mucho ver esas dos ultimas formas de hacerlo, sobre todo la que propone leosansan, deduzco que
Código (cpp) [Seleccionar]
variable = variable + algo. /* Es lo mismo que*/ variable += algo
Lo de las librerias tengo que tener cuidado por lo que veo.


Gracias un saludo!!
 
Título: Re: Problema con errorC2296 en C++
Publicado por: leosansan en 23 Marzo 2014, 16:21 PM
Cita de: Feynmann en 23 Marzo 2014, 15:56 PM
Me ha molado mucho ver esas dos ultimas formas de hacerlo, sobre todo la que propone leosansan, deduzco que
Código (cpp) [Seleccionar]
variable = variable + algo. /* Es lo mismo que*/ variable += algo
Lo de las librerias tengo que tener cuidado por lo que veo.


Gracias un saludo!!
 

Gracias, gracias, me alegra que te haya gustado el "mas_menos".  ;)

Y sí, son formas equivalentes y más usuales:


Código (cpp) [Seleccionar]
variable = variable + algo. /* Es lo mismo que*/ variable += algo

Código (cpp) [Seleccionar]
variable = variable * algo. /* Es lo mismo que*/ variable *= algo

Código (cpp) [Seleccionar]
variable = variable - algo. /* Es lo mismo que*/ variable -= algo

Código (cpp) [Seleccionar]
variable = variable / algo. /* Es lo mismo que*/ variable /= algo

Y alguna más.

Y lo de las librerías no estaba mal en si, sólo que sobraban y es un "cante" para si te corrige algún profesor darse cuenta de tus lagunas, que tenerlas las tendrás, como todos, pero una máxima del estudiante es que al menos no se noten.

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: Problema con errorC2296 en C++
Publicado por: Feynmann en 23 Marzo 2014, 18:28 PM
Gracias de nuevo por el aporte!

Que va, estoy aprendiendo por mi cuenta para poder implementarlo a cosillas del curro que necesito... ya me gustaria estar estudiando! jajaja
Título: Re: Problema con errorC2296 en C++
Publicado por: Yoel Alejandro en 24 Marzo 2014, 20:47 PM
Me perdí de un rato en el foro, pero bueno .....

Respecto a getchar() y system("PAUSE"), aunque operan similarmente, la primera es estándar y funcionará en cualquier sistema. La segunda, se puede garantizar siempre que estés en un sistema Windows.

Lo que ocurre es que system(str) pasa la cadena str al procesador de comandos del sistema operativo. Hacer system(str) es lo mismo que abrir el Símbolo de Sistema de Windows y escribir el contenido de la cadena str en él. Y como es de suponer, la cadena será interpretada en el contexto del sistema operativo de que se trate.

Por esta razón, recomendamos usar getchar() que tiene un comportamiento predecible. Lo que hace

c = getchar();

es esperar la pulsación de una tecla, seguida de ENTER (o de la secuencia EOF) y depositar el código ASCII de esta tecla en c. Si pulsas 'A' y luego ENTER asignará en c el valor 97 que es el código ASCII de la letra 'a'.
Si pulsas sólo ENTER entonces retornará al programa inmediatamente. Por eso la invocación de getchar() es para los programadores de C un equivalente a "Pulse ENTER para continuar", jejeje.

=====================================
De todas las soluciones publicadas creo que la mejor (más eficiente computacionalmente) sería la de leosansan porque no requiere siquiera calcular el módulo i%2. Yo la reduciría "un pelín" con:

int signo = -1;

for (i = 1;  i<= n; i++, signo *= -1)
   pi = pi + signo * 1.0/(2*i+1);


y buena la observación del "1." en lugar de "1".