Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - xoker

#1
Programación C/C++ / Re: Double en C
19 Julio 2014, 13:27 PM
Ya la verdad que tengo curiosidad, os ha pasado a vosotros anteriormente? es esto algo nuevo de la ultima version del compilador?

La verdad que me he llevado una gran sorpresa!
#2
Programación C/C++ / Double en C
19 Julio 2014, 11:16 AM
Buenas a todos, vereis despues de muchisimo tiempo me he encontrado con un problema con los double en C, es con el siguiente codigo:

#include <stdio.h>

int main(){

double a;

printf("Introduce un valor: ");
scanf("%f",&a);

printf("%f",a);

system("pause");
return 0;
}


Como podeis ver, no puede ser un codigo mas tonto, leo un double por teclado y lo imprimo por pantalla. Pues bien, introduzca el numero que introduzca, siempre me sale 0 por pantalla, tras pasarle el depurador, sucede que en el momento de hacer el scanf lo que lee no es el numero que yo meto, sino que introduce en la variable un numero en notacion cientifica bajisimo, muy proximo a cero, por eso por pantalla aparece el cero. Tambien he probado a quitar el scanf y darle yo un valor a mano a la variable y se imprime correctamente, por lo que confirmo que la culpa es del scanf.

Para solucionar este error, lo que he hecho a la hora de leer por teclado es sustituir scanf("%f", &a); por scanf("%lf",&a); es decir, en vez de usar %f uso %lf y ya funciona correctamente.

¿Es todo esto normal? Yo juraria que en mis mas de dos años usando C, nunca he tenido este problema. Realmente no me ha ocurrido a mi originalmente, le ocurrio a un amigo y cuando fui a probar en mi PC tambien ocurria lo mismo, ambos tenemos el compilador MingGW GCC 4.8.1.

Por ultimo, he mirado en internet y libros y todos lo hacen como yo  :o, con un scanf("%f",...).

Un saludo.
#3
Tienes varias opciones, una poco eficiente seria contar el numero de '\n' que hay en el fichero mirando uno a uno cada caracter y cada vez que el caracter sea igual a '\n' sumas 1 en un contador.

Otra opcion es contar el numero de lineas, esta opcion es mas eficiente, en este video se explica exactamente como contar las lineas de un fichero:

[youtube=640,360]https://www.youtube.com/watch?v=hC2lrn81eco&list=PLw8RQJQ8K1ySN6bVHYEpDoh-CKVkL_uOF&index=42[/youtube]

Esta al comienzo! Espero que te sirva, un saludo.
#4
Cita de: ivancea96 en 17 Abril 2014, 14:05 PM
Tienes errores ortográficos (Ej. "deplaza" en vez de "desplaza").
Algunas funciones del .cpp no concuerdan con el .h en cosas como el const, por ejemplo.

¿Compilas en Windows o en Unix?

Luego, pones cosas como "stricmp(op1, op2)". ¿Comparas chars con stricmp?

No se qué decir. Deberías replantearte muchas cosas. Ve reparando errores de las funciones 1 a 1.

Buenas tio, pues la verdad que me dejas peor de lo que empece, porque aunque no controlo C++ (soy de C y Java), creo que el .h corresponde con el .cpp, aunque claro que no pongo la mano en el fuego, podrias iluminarme? porque no veo lo que tratas de decirme.

Despues sobre el const, es totalmente cierto, no lo controlo, tanto es asi, que creo que el fallo del operador de conversion a char* tiene que venir de ahi, pero no consigo resolverlo. Podrias indicarme lo que ves mal en el codigo? Y si tienes la solucion para lo del operador de conversion char* te lo agradeceria mucho.

Por ultimo, sobre el usar stricmp para comparar caracteres, lo uso, porque tal como comente al principio estoy tratando de hacer una simulacion de la clase string de C++ y uso algunas funciones cuando puedo de la biblioteca string.h de C, si crees que hay una forma mas correcta soy todo oidos!!

Muchas gracias!!

EDITO: Compilo en windows con Dev C++




Zasca!! Me respongo a mi mismo! Encontrado el fallo del operador de conversion, resulta que la funcion strcpy recibe lo siguiente:

strcpy (char *op1, const char *op2); y donde me daba fallo era en op1 porque tenia un operador de conversion const char y no tenia el operador de conversion char... vergonzoso error que me traia de cabeza!!

Esto es lo que le ocurre cuando uno se adapta a lenguajes tan sencillos como Java  >:( >:(
#5
Nada chicos, ni una cosa ni la otra, da exactamente el mismo error.

Os pongo aqui ambos archivos completos, el .cpp y el .h, quizas sea de otra cosa que no veo.

El .cpp:

#include <iostream>
#include <cstring>
#include "cadena.h"


Cadena::Cadena(unsigned tam, char relleno): _tamano(tam){
_palabra = new char[_tamano + 1];

for(int i = 0 ; i < _tamano; i++){
_palabra[i] = relleno;
}

_palabra[_tamano] = '\0';
}

Cadena::Cadena(const Cadena& copia){
_tamano = copia._tamano;
strcpy(_palabra, copia._palabra);
}

Cadena::Cadena(char* palabra_aux){
_tamano = strlen(palabra_aux);
strcpy(_palabra, palabra_aux);
}

Cadena& Cadena::operator = (char* palabra_aux){
Cadena auxiliar(strlen(palabra_aux));
strcpy(auxiliar._palabra, palabra_aux);
return auxiliar;
}

Cadena& Cadena::operator = (const Cadena& copia){
Cadena auxiliar(copia);
return auxiliar;
}

Cadena::operator const char*() const{
return (const char*)_palabra;
}

Cadena& operator +(const Cadena& op1, const Cadena& op2){
Cadena auxiliar(op1.length() + op2.length() + 1);

strcpy(auxiliar, op1);
strcat(auxiliar, op2);

return auxiliar;
}

char Cadena::operator[] (int i) const{
return _palabra[i];
}

char Cadena::at(int i){
char caracter;
if(i < _tamano && i > 0){
caracter = _palabra[i];
}
else{
throw std::out_of_range("Fuera de Rango");
}

return caracter;
}

bool operator ==(const Cadena& op1, const Cadena& op2){
bool resultado = true;

resultado = !(stricmp(op1, op2));

return resultado;
}

bool operator !=(const Cadena& op1, const Cadena& op2) const{
return !(operator == (op1, op2));
}

bool operator > (const Cadena& op1, const Cadena& op2){
bool resultado;
int cantidad = 0;

for(int i = 0; cantidad == 0 && !(op1[i] == '\0' && op2[i] == '\0'); i++){
cantidad = stricmp(op1[i], op2[i]);
}

if(cantidad > 0){
resultado = true;
}
else{
resultado = false;
}
return resultado;
}

bool operator < (const Cadena& op1, const Cadena& op2){
bool resultado;
int cantidad = 0;

for(int i = 0; cantidad == 0 && !(op1[i] == '\0' && op2[i] == '\0'); i++){
cantidad = stricmp(op1[i], op2[i]);
}

if(cantidad < 0){
resultado = true;
}
else{
resultado = false;
}
return resultado;
}

bool operator <= (const Cadena& op1, const Cadena& op2){
bool resultado;
int cantidad = 0;

for(int i = 0; cantidad == 0 && !(op1[i] == '\0' && op2[i] == '\0'); i++){
cantidad = stricmp(op1[i], op2[i]);
}

if(cantidad <= 0){
resultado = true;
}
else{
resultado = false;
}

return resultado;
}

bool operator >= (const Cadena& op1, const Cadena& op2){
bool resultado;
int cantidad = 0;

for(int i = 0; cantidad == 0 && !(op1[i] == '\0' && op2[i] == '\0'); i++){
cantidad = stricmp(op1[i], op2[i]);
}

if(cantidad >= 0){
resultado = true;
}
else{
resultado = false;
}

return resultado;
}

int Cadena::length() const{
return _tamano;
}

Cadena Cadena::substr (unsigned inicio, unsigned desplaza){
int limite = inicio + desplaza;
char palabra_auxiliar[desplaza + 1];
Cadena auxiliar(deplaza+1);
if(inicio + desplaza > _tamano){
throw std::out_of_range("Fuera de Rango");
}
else{
for(int i = 0 ; i < desplaza ; i++){
palabra_auxiliar[i] = _palabra[inicio + i];
}
}
auxiliar = palabra_auxiliar;
return auxiliar;
}

Cadena::~Cadena(){
delete[] _palabra;
}


Ahora el .h:

#ifndef CADENA_H_
#define CADENA_H_

class Cadena{
public:
Cadena(unsigned tam = 1, char relleno = ' ');
Cadena(const Cadena& copia);
Cadena(char* palabra_aux);
Cadena(const char*);
Cadena& operator = (char* palabra_aux);
Cadena& operator = (const Cadena& copia);
char operator[] (int i);
operator const char*() const;

int length() const;
char at(int i);
Cadena substr (unsigned inicio, unsigned desplaza);

~Cadena();

private:
int _tamano;
char* _palabra;
};


Cadena& operator +(const Cadena& op1, const Cadena& op2);
bool operator ==(const Cadena& op1, const Cadena& op2);
bool operator !=(const Cadena& op1, const Cadena& op2);
bool operator > (const Cadena& op1, const Cadena& op2);
bool operator >= (const Cadena& op1, const Cadena& op2);
bool operator < (const Cadena& op1, const Cadena& op2);
bool operator <= (const Cadena& op1, const Cadena& op2);

#endif



Muchas gracias por echarle un ojo!!
#6
Buenas a todos estoy aprendiendo C++ y tengo un problema con el operador de conversion en un programa que estoy haciendo para ver como se usa, pongo aqui el codigo de una clase llamada Cadena, el objetivo del codigo es hacer una burda implementacion de la clase string de C++, para ello uso algunas funciones de la biblioteca cstring de C:



//El .h de la clase resumido:

class Cadena{
public:
               //Constructores:
Cadena(unsigned tam = 1, char relleno = ' ');
Cadena(const Cadena& copia);
Cadena(char* palabra_aux);
Cadena(const char*);
               
               //Aqui cabecera del metodo del operador de conversion
operator const char*() const;

~Cadena();

private:
int _tamano;
char* _palabra;
};

//Pongo fuera aposta este metodo para que realice la operacion de conversion.
Cadena& operator +(const Cadena& op1, const Cadena& op2);


//El .cpp de la parte que nos interesa:

Cadena& operator +(const Cadena& op1, const Cadena& op2){
Cadena auxiliar(op1.length() + op2.length() + 1); //Lo que hago es crear un                    //nuevo objeto y reservar espacio para el char* que voy a meterle.

strcpy(auxiliar, op1); // <-- Aqui es donde peta!
strcat(auxiliar, op2);

       return auxiliar;
}

Cadena::operator const char*() const{
return _palabra;
}



Lo que yo trado de hacer es lo siguiente:

-Como no puedo acceder a los atributos privados desde un metodo externo a la clase, en strcpy (auxiliar. op1) lo que hago con auxiliar es pasarle el objeto y como deberia de recibir un char*, va al operador de conversion de tipo char* y me transforma el objeto en un char* listo para strcpy... O eso es la teoria porque me da el siguiente error (entre un monton mas de otros temas...)

El error que que da es este:

[Error] invalid user-defined conversion from 'Cadena' to 'char*' [-fpermissive]
[Note] candidate is: Cadena::operator const char*() const <near match>
[Note] no known conversion for implicit 'this' parameter from 'const char*' to 'char*'

A ver si teneis idea de cual es el problema!!

Muchas gracias y un saludo!!
#7
Programación C/C++ / Re: Hola Soy nuevo[DUDA]
7 Febrero 2014, 21:45 PM
Buenas, tal como te comentan eso es una funcion, sobre el paso por referencia, valor, parametros y demas, te dejo aqui un video que hice yo mismo hace tiempo donde se explica que es una funcion, como usarla, etc... Son unos cuantos videos, por lo que puedes ver los que quieras:

[youtube=640,360]https://www.youtube.com/watch?v=Vc37jP4hE1s&list=PLw8RQJQ8K1ySN6bVHYEpDoh-CKVkL_uOF&index=18[/youtube]

Aqui te pongo el primer video de funciones.

Un saludo.
#8
Cita de: ~ Yoya ~ en 26 Enero 2014, 16:08 PM

Si dices eso, donde debo poner ese código?? según tu comentario antes del switch, porque no vas a declarar un atributo estático dentro de un método. Me dices que lo coloque antes del switch, posteo el codigo de como debe quedar segun usted y luego me dices que el codigo es mio y que es una bestia jejeje

Yo hasta ahora he tratado simular tu código porque nomas haz puesto código que no funcionan, malas indicaciones, o simplemente que funcionan pero estan mal hecho, y encima pones que mis codigo son bestiales y lo único que he hecho es seguir sus indicaciones para tratar de dar con el código que suyo que no funciona y que hasta ahora es que lo agrega al topic, para poder ver el problema y mirar que pasa... Pero el codigo malo que tienes me dices con son míos. Y en este punto es que haz puesto el código que deberías haber puesto al principio del hilo.

Men si eres tan buen programador, entonce hubieras arreglado y encontrado la razón porque pasa lo que pasa, ya que simplemente el error es básico.

Saludos y debuguea.

Este es el ultimo mensaje que escribo en el hilo.

Desde el inicio el codigo que tengo en mi PC funciona perfectamente (al copiarlo me puse una llave de mas, error mio que ni siquiera sabia que habia puesto y que imagino que nadie se dio cuenta al principio hasta que lo mencionaste mas tarde), el unico problema que tiene el codigo es que cuando pongo un cerrojo de tipo Integer y lo uso, el cerrojo deja de hacer su funcion de cerrojo y deja pasar a todo el mundo. Si uso un cerrojo por ejemplo de tipo Object el codigo funciona perfectamente.

Mi duda es y siempre ha sido la siguiente: ¿Por que cuando uso un cerrojo de tipo Integer y lo uso como un entero el cerrojo deja de funcionar?

Nada mas y nada menos, creo que en el primer post y en los sucesivos lo he preguntado siempre...

Por ultimo solo decir, que dije que tus codigos eran bestialidades, por varias razones:

-Hacer un cerrojo No estatico no vale para nada.
-Declarar un cerrojo dentro de un metodo no vale para nada.
-Poner el synchronized que ocupa todo el switch deja sin paralelismo.
-Poner el synchronized que ocupa todo el for vuelve a dejar sin paralelismo.

Esto se estudia al comienzo en la universidad, lo se porque en segundo de carrera estoy cursando una asignatura sobre paralelismo y todos lo hacemos al principio... y con el tiempo, ves la burrada que significa.

Aun asi muchas gracias por haber tratado de ayudarme.

Un saludo.
#9
Cita de: ~ Yoya ~ en 25 Enero 2014, 00:04 AM
Me hubiera alegrado que en vez de decir que entiendes mi código, hubieras dicho que entiendes y comprendes la definiciones que deje...



Brother, tu código no funciona con "cerrojo" del tipo int o de cualquier tipo. Tu codigo debe imprimir 0, ya que primero se incrementa a 10,000 y luego descrementa a 0, en cambio retorna 10,000.

Otra cosa, las definiciones no es para que entiendas mi código, el código que puse es lo de menos pero te haz centrado hay. Las definiciones que deje es para que entiendas que si varios threads están modificando el mismo recurso a la vez, te causara conflictos.

Por la llave del case 1 después del for, hace que se ejecute el for 1 vez, ya que va a procesar el break porque este esta dentro de la llaves.




Pero vamos a ver hombre de dios... Cuando dos threads acceden al mismo recurso compartido y lo modifican, se produce una cosa que se llama indeterminacion, que significa que el resultado que va a dar va a ser diferente cada vez. Para controlar esta indeterminacion la teoria es acceder al recurso compartido de forma atomica, es decir, que solo acceda de uno en uno a la variable compartida, para hacer esto se emplean varias tecnicas diferentes, entre otras (y la peor en rendimiento) es el synchronized. En el codigo anterior que yo puse, la llave esa se me colo al copiar, fallo mio, .

CitarAqui esta el famoso codigo con cerrojo del tipo objeto,mira que no funciona:

Código (java,14,17,18,21,22) [Seleccionar]
package main;


public class Hilo extends Thread {
   private int tipoHilo;
   private  static Integer n = new Integer(0);
   private int nVueltas;

   public Hilo(int nVueltas, int tipoHilo)
   {this.nVueltas=nVueltas; this.tipoHilo=tipoHilo;}

   public void run()
   {
     Object cerrojo = new Object();
     switch(tipoHilo){
       case 0:
        for(int i=0; i<nVueltas; i++)
        synchronized(cerrojo){ n=n+1;};
        break;
       case 1:
        for(int i=0; i<nVueltas; i++)
        synchronized(cerrojo){n=n-1;};
        break;
     }
   }

 public static void main(String[] args)
     throws Exception
 {
     Hilo p = new Hilo(10000, 0);
     Hilo q = new Hilo(10000, 1);
     p.start();
     q.start();
     p.join();
     q.join();
     System.out.println(n);
 }

}

Este codigo refleja que no sabes controlar la exclusion mutua, no hay problema, yo te enseño como se hace, pero no me digas que lo mas basico de programacion concurrente no se puede hacer, un "lo desconozco" es mejor que una mentira.

Para que te quede claro, el primer error y mas bestial que he visto en tu codigo es que declaras el objeto dentro del void run() ¿?¿?¿?¿?!!! Eso lo que hace es que cada hilo tenga su propio cerrojo, por tanto no se podra controlar la exclusion mutua, hay que declararlo como un atributo de la clase siendo de tipo static, para que todos los objetos compartan el mismo valor.

Aqui te pongo el codigo original, copiado y pegado cambiando solo el cerrojo y la llave y comprobado que funciona, siempre te dara 0 a pesar de todo lo que has comentado del synchronized:

import java.util.concurrent.*;

public class Hilo extends Thread {
   private int tipoHilo;
   private  static Integer n = new Integer(0);
   private int nVueltas;
   private static Object cerrojo = new Object();

   public Hilo(int nVueltas, int tipoHilo)
   {
    this.nVueltas=nVueltas;
    this.tipoHilo=tipoHilo;
   }

   public void run()
   {
     
     switch(tipoHilo){
       case 0:
        for(int i=0; i<nVueltas; i++)
        synchronized(cerrojo){ n=n+1;};
        break;
       case 1:
        for(int i=0; i<nVueltas; i++)
        synchronized(cerrojo){n=n-1;};
        break;
     }
   }

 public static void main(String[] args)throws Exception
 {
     Hilo p = new Hilo(10000, 0);
     Hilo q = new Hilo(10000, 1);
     p.start();
     q.start();
     p.join();
     q.join();
     System.out.println(n);
 }
}


Un saludo y me quede con la duda de el dichoso cerrojo Integer...
#10
Vaya... ambos estais comentiendo errores importantes, muy importantes.

Estais convierto un codigo que se ejecuta en paralelo en un codigo secuencial. Yoyas me puedes poner todas las definiciones que quieras, yo entiendo a la perfeccion tu codigo, no esta mal, funciona, pero funciona de manera sencuencia mientras que el mio funciona de manera paralela por lo que aprovecha todos los nucleos de la CPU mientras que el tuyo solo uno.

Da la casualidad de que en este caso, mi codigo solo realiza una operacion dentro de los cases del switch, pero contra mas operaciones independientes tenga, mas rapido seria con respecto al tuyo, ya que tu solo haces un case del switch a la vez mientras que yo hago los dos al mismo tiempo. Con ese codigo te suspenden rapido en cualquier asignatura de programacion concurrente.

Vuelvo a repetir, que si mi codigo se cambia el esta parte:

switch(tipoHilo){
       case 0:
        for(int i=0; i<nVueltas; i++)
        synchronized(n){ n=n+1;};
        break;
       case 1:
        for(int i=0; i<nVueltas; i++){
        synchronized(n){n=n-1;};
        break;
     }


por:
//Supongamos que antes se ha declarado esto:
//Object cerrojo = new Object();

switch(tipoHilo){
       case 0:
        for(int i=0; i<nVueltas; i++)
        synchronized(cerrojo){ n=n+1;}; // <--- Cambio de cerrojo
        break;
       case 1:
        for(int i=0; i<nVueltas; i++){
        synchronized(cerrojo){n=n-1;}; // <--- Cambio de cerrojo
        break;
     }


El codigo funciona perfectamente y en paralelo, lo unico que no comprendo es el porque cuando utilizo un objeto como cerrojo (el integer n en el primer ejemplo) y le cambio su valor, este pierde su cualidad de cerrojo... nada mas!!