miércoles, 8 de noviembre de 2017

Reentrada

Aquí estamos otra vez después de unos años. Me ha costado entrar a redactar por culpa de todo ese tema de claves y contraseñas, que ya tenía olvidadas, pero lo hemos superado (ni siquiera sé cómo). Ahora procuraré guardar toda esa herramienta en un cajón por si acaso me vuelvo a encontrar en apuros a la vuelta de la esquina. Mucho no se me ocurre contar por el momento, pero ya irán saliendo temas. Yo empecé en esto de los blogs por curiosidad para saber cómo se hacían. Estuve activo unos años, hasta hice algunas amistades de esas cibernéticas, pero en cuento empecé con Facebook me fui al otro barrio por aquello de que resulta mucho más fácil y menos trabajoso. Pero también algo más aburrido. Ayer estuve leyendo mi blog que sigue ahí tan impertérrito y me gustó. Entonces decidí empezar de nuevo. A ver...
Saludos a todas mis viejas amistades desde aquí por si a alguno o a alguna se le ocurre visitarme en este rincón del espacio virtual. Y ahora una imagencita:

Bueno, pues por hoy basta. Para empezar es suficiente. La imagen es de un cuadro de Camilo Pisarro.

martes, 13 de agosto de 2013

Bucles encajados


Aquí ponemos un programa para presentar en pantalla una tabla, en este caso de multiplicar, pero podría ser de cualquier otra cosa. Se hace mediante lo que se llama un par de bucles encajados. Es un problema clásico.

/*El uso de While. Tabla de multiplicar. Contiene 2 bucles anidados */
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
  int i=2,j,k,m,R;
  cout<<endl;
  //**Impresión de cada línea de la tabla**
  while (i<=9){
    j=2;
    while (j<=9){
      cout<<i<<"*"<<j<<" ="<<setw(3)<<right<<i*j<<" | ";
      j++;
    }
    cout<<endl;
    //**Renglón**
    m=0;
    while (m<=7){
      if (m==0) R=8; else R=9;
      for(k=0;k<=R;k++) cout<<"-";
      cout<<"|";
      m++;
    }
    //-----------
    i++;
    cout<<endl;
  }
  //**Termina bucle principal**
  cout<<endl;
  return 0;
}

jueves, 8 de agosto de 2013

Fracción propia y decimal


Este programa convierte una fracción propia - aquella cuyo numerador es menor que el denominador - en una fracción decimal. El sistema no es directo, dividiendo un número por otro como números reales. Ahí está la gracia, sino que se tratan los dos números en todo momento como números enteros. En realidad es lo mismo que haríamos con lápiz y papel y un poco de paciencia, porque saca 20 decimales.

#include<iostream>
#define N 20
using namespace std;
int main()
{
long int dv,ds,q=1,Q,R;
int i,d[N];
for(i=0;i<N;i++) d[i]=0;
cout<<"\tVamos a transformar una fracción propia,\n"
<<"\ten la que el numerador es menor que el denominador,\n"
<<"\ten una decimal\n";
ini:
cout<<"Dame el numerador N de la fracción: ";
cin>>dv;
cout<<"Dame en denominador D de la fracción: ";
cin>>ds;
if(dv>=ds) {cout<<"¡Error, repita, por favor!\n";goto ini;}
//----
while(q*ds<=dv)
q++;
Q=q-1;
R=dv;
for(i=0;i<N;i++){
if(R==0) break; 
else {
dv=R*10;q=1;
while(q*ds<=dv)
q++;Q=q-1;
R=dv-Q*ds;
d[i]=Q;
}
}
cout<<"La fracción decimal es: 0,";
for(i=0;i<N;i++) cout<<d[i];
cout<<endl;
return 0;
}

sábado, 13 de julio de 2013

Suma y resta atípicas


Nulla dies sine linea, decían los romanos. Así que no vamos a dejar pasar un día más sin poner algo aquí. Son programas sencillos que van señalando mis aventuras con el C++,  y los pongo aquí por si a alguien le sugieren algo.  Hoy traigo dos programas. Los llamo suma, resta atípicas, porque, como digo en los programas, las operaciones aritméticas - suma, resta, multiplicación y división - se reducen a contar hacia adelante o hacia atrás. Todo es contar al fin de cuentas. Creo que se podría demostrar que hasta las matemáticas más abstrusas en el fondo se reducen a los números naturales: 1, 2, 3,... infinito. Bueno, por el momento vamos a dejar estas filosofías para otro día. Estos dos programas suman y restan sencillamente contando mediante un bucle cuanto pasa o cuanto queda hasta un número determinado.

#include<iostream>
using namespace std;
int main()
{
long int m,n,i;
long int contador=0;
cout<<"\n\tSUMA ATÍPICA\n";
cout<<"\tLAS OPERACIONES ARITMÉTICAS SE REDUCEN SIEMPRE A CONTAR\n";
cout<<"\tHACIA ADELANTE O HACIA ATRÁS.\n";
init:
cout<<"\tDame el primer sumando: ";
cin>>m;
cout<<"\tDame el segundo sumando: ";
cin>>n;
cout<<"\tVamos a sumar "<<n<<" con "<<m<<endl;
contador=m;
for(i=0; i<n; i++)
contador++;
cout<<"\tHemos obtenido el resultado: "<<contador<<" \n"<<endl;
return 0;
}

_____________________________________________

#include<iostream>
using namespace std;
int main()
{
long int m,n,i;
long int contador=0;
cout<<"\n\tRESTA ATÍPICA\n";
cout<<"\tLAS OPERACIONES ARITMÉTICAS SE REDUCEN SIEMPRE A CONTAR\n";
cout<<"\tHACIA ADELANTE O HACIA ATRÁS.\n";
init:
cout<<"\tDame el minuendo: ";
cin>>m;
cout<<"\tDame el sustraendo: ";
cin>>n;
if(n>m){
cout<<"\tEl minuendo ha de ser mayor que el sustraendo\n";
goto init;
}
cout<<"\tVamos a restar "<<n<<" de "<<m<<endl;
for(i=n; i<m; i++)
contador++;
cout<<"\tHemos obtenido el resultado: "<<contador<<" \n"<<endl;
return 0;
}

sábado, 15 de junio de 2013

Alcance del tiro parabólico


Este programa sigue en la misma línea del anterior. Se trata de resolver problemas tipo y típicos mediante un programa que espera unos datos numéricos introducidos por teclado. La máquina hace todas las operaciones necesarias y proporciona las ecuaciones adecuadas. Este de hoy es un problema clásico: se trata de determinar el alcance de un disparo parabólico a partir de la velocidad inicial y de la inclinación sobre el suelo. Para resolverlo se descompone la velocidad inicial en dos componentes: la velocidad horizontal y la vertical. Contra esta trabaja la gravedad. De esta forma obtenemos dos ecuaciones para el desplazamiento: sy=vy*t + ½g*t²  y   sx=vx*t, siendo sy y sx los desplazamientos vertical y horizontal. Teniendo en cuenta que g es negativa en el ascenso y que cuando el proyectil llega al suelo sy=0 obtenemos una ecuación de 2º grado que resolvemos para t. Una vez obtenido t resolvemos la segunda ecuación para obtener sx.
Combinando estos cálculos llegamos a la fórmula sintética, que también podemos emplear: 
sx= v²*sin(2a)/g.
En esa fórmula podemos ver dos cosas: que el alcance depende fuertemente de la velocidad inicial y que es máximo para 45º, pues seno(2*45) = seno (90) = 1. También podemos derivar respecto a  'a', sx' = v²/g cos(2a) y ver que para a=pi/4  cos(pi/2)=0, marcando el máximo de la primitiva.
P.D. He añadido una linea al programa para calcular la altura máxima que alcanza el proyectil en su movimiento parabólico. La fórmula es sy=v²*sin²(a)/2*g.
Esta fórmula se puede obtener fácilmente derivando respecto de t  sy=v*sin(a)*t + ½g*t² e igualando a cero. Obtenemos t=2*v*sin(a)/g. Sustituyendo este valor de t en la función sy obtenemos la fórmula.


#include<iostream>
#include<cmath>
#define g 9.81
#define pi 3.14159265
using namespace std;
int main()
{
//Variables
double v,vx,vy; //velocid. inicial, componentes de la velocidad.
double a,sx,t; //ang. inclin.,distancia horiz.,tiempo empleado
cout<<"\n\tCalcular el alcance de un proyectil lanzado con una velocidad \n";
cout<<"\tinicial 'v' y con un angulo de inclinación sobre el suelo 'alfa'.\n"<<endl;
//Entrada de Datos
cout<<"Dame velocidad del disparo (metros/seg): ";cin>>v;
cout<<"Dame ángulo de inclinación (grados): ";cin>>a;
a=a*pi/180; //conversión a radianes
//Fórmulas: componentes de la velocidad
vx=v*cos(a);
vy=v*sin(a);
//Solución de la ecuación de 2º grado: -9.8*t*t/2 + vy*t=0, pues cuando llega al suelo sy=0
t=vy/(g/2);
sx=vx*t;
//También: sx=v*cos(a)*v*sin(a)/(g/2) ==> sx=v²sin(2a)/g
//Resultados
cout<<"El alcance del disparo es: "<<sx<<" ms."<<endl;
cout<<"El tiempo que tarda en alcanzar el objetivo es: "<<t<<" seg."<<endl;
cout<<"La altura máxima que alcanza es: "<<v*v*sin(a)*sin(a)/(2*g)<<" ms."<<endl;
return 0;
}

jueves, 13 de junio de 2013

Las máquinas y los problemas



Una cosa que siempre me atrajo es esta de resolver "problemas tipo". Me explico: Ya que tenemos "máquinas calculadoras" que son los ordenadores - que para eso nacieron fundamentalmente - vamos a dejarle a la máquina hacer todos los cálculos con los datos que le entreguemos y el programa adecuado en cada caso. Los datos pueden ser cualesquiera - eso sí, dentro de un orden - y la máquina se encargará de hacer los cálculos. Esto de hacer los cálculos, me temo yo, pasará en el futuro completamente a su dominio. Pero lo que nunca podrán hacer las máquinas son los planteamientos y la utilización de las fórmulas adecuadas. Eso es lo que nosotros les proporcionamos por medio del programa. Programar debiera ser tan fácil como escribir una carta o redactar un mensaje. Y todo el mundo debiera saber hacerlo. Es lo que apareció con aquellas calculadoras de hace 30 años "programables". Aquello nos parecía una "pasada" y realmente que lo era. Pues ahora lo tenemos mucho más fácil con los lenguajes de programación. Y sin embargo probablemente lo despreciamos porque pretendemos hacer programas más "sofisticados" y huimos de lo trillado. Pues bien, he aquí un ejemplo de lo que pretendo decir. Este es un problema tipo y típico de plano inclinado y aceleraciones. Como este se pueden hacer miles y convendría ejercitarse para llegar a dominar completamente esta forma de proceder. En la segunda pantalla hay un pequeño error: la aceleración debe ser dada en mts/seg².


#include<iostream>
#include<cmath>
using namespace std;
#define pi 3.1415926
#define g 9.81
int main()
{
double s,t,v;
double a,t_v,s_v;
double h,i_p;
//Texto
cout<<"\n\t  Un cuerpo, partiendo del reposo, cae por un \n";
cout<<"\t  plano inclinado con un aceleración uniforme\n";
cout<<"\t  recorriendo 'x' metros en 't' segundos.\n";
cout<<"\t  ¿Cuanto tiempo tardará en adquirir una velo-\n ";
cout<<"\t  cidad 'v' desde que empieza a moverse?"<<endl;
cout<<endl;
//Datos
ini:
cout<<"Dame el espacio recorrido por el cuerpo en su descenso por el plano (m): ";cin>>s;
cout<<"Dame el tiempo empleado en recorrer ese espacio (seg): ";cin>>t;
a=(2*s)/(t*t); //cálculo de la aceleración
if(a>=g) {cout<<"Imposible, hay un error. \n";goto ini;} //no se puede alcanzar la aceleración de la gravedad
cout<<"Dame la velocidad final que debe llegar a alcanzar (m/s): ";cin>>v;
//Otras fórmulas
t_v=v/a; //tiempo para alcanzar velocidad final
s_v=a*t_v*t_v/2; //espacio recorrido
h=a*s_v/g; //altura del plano
i_p=asin(h/s_v); //ángulo de inclinación
//Resultados
cout<<"La aceleración del movimiento es de "<<a<<" m/s. "<<endl;
cout<<"El tiempo que tardará en adquirir esa velocidad es de "<<t_v<<" seg. "<<endl;
cout<<"Para entonces el cuerpo habrá recorrido un espacio de "<<s_v<<" metros"<<endl;
cout<<"Comprobación: La velocidad final al cuadrado ha de ser igual al doble de la\n";
cout<<" aceleración por el espacio recorrido. Efectivamente, velocidad final² = "<<v*v<<endl;
cout<<"Y el doble de la aceleración por el espacio recorrido: "<<2*a*s_v<<endl;
cout<<"La altura desde la que cayó ese cuerpo para adquirir esa velocidad es de "<<h<<" m"<<endl; 
cout<<"Y la inclinación del plano "<<i_p*180/pi<<" grados."<<endl;
return 0;
}


jueves, 6 de junio de 2013

Un ejemplo de programación POO



Este programa lo he tomado del libro de Francisco Javier Ceballos "C++ orientado a objetos". Nos indica un poco cómo funciona esto de la programación orientada a objetos. Es un ejemplo elemental de administración de una cuenta en un banco, por ejemplo. Está ligeramente retocado, porque hay algunas cosas que no entiendo.


#include<iostream>
#include<string>
using namespace std;
class CCuenta
{
//Atributos
private:
string nombre;
string cuenta;
double saldo;
double tipoInteres;
//Métodos
public:
void asignarNombre(string nom){
if(nom.length()==0){ cout << "error: cadena vacía\n"; return;}
nombre=nom;
}
string obtenerNombre(){
return nombre;
}
void asignarCuenta(string cue){
if (cue.length()==0){cout << "Error: cuenta no válida\n";return;}
cuenta = cue;
}
string obtenerCuenta(){
return cuenta;
}
void asignarRemanente(double remanente){
saldo=remanente;
return;
}
double estado(){
return saldo;
}
void ingreso(double cantidad) {
if (cantidad<0){cout<<"Error: cantidad negativa\n";return;}
saldo=saldo+cantidad;
}
void reintegro(double cantidad){
if(saldo - cantidad <0) {cout <<"Error: No dispone de saldo\n";return;}
saldo = saldo - cantidad;
}
void asignarTipoDeInteres(double tipo){
if (tipo<0) {cout <<"Error: Tipo no válido\n";return; }
tipoInteres = tipo;
}
double obtenerIntereses(){
return saldo*tipoInteres/100;
}
};
int main(){
string num,nombre;
double interes, cantidad, salida, remanente;
CCuenta cuenta01; //Asignación de un objeto a la clase CCuenta
cout<<"Déme el nombre del titular de la cuenta: ";getline(cin,nombre);
cuenta01.asignarNombre(nombre);
cout<<"Déme el número de su cuenta: ";cin>>num;
cuenta01.asignarCuenta(num);
cout<<"Déme el remanente de su cuenta: ";cin>>remanente;
cuenta01.asignarRemanente(remanente);
cout<<"¿Cuánto va a ingresar? ";cin>>cantidad;
cuenta01.ingreso(cantidad);
cout<<"¿Cuánto va a sacar?: ";cin>>salida;
cuenta01.reintegro(salida);
cout<<"El titular de la cuenta es el Sr. "<<cuenta01.obtenerNombre()<<endl;
cout<<"Su número de cuenta es "<<cuenta01.obtenerCuenta()<<endl;
cout<<"El estado de su cuenta es "<<cuenta01.estado()<<endl;
cuenta01.asignarTipoDeInteres(2.5);
cout<<"Los intereses que producirán su depósito al 2.5 % son "<<cuenta01.obtenerIntereses()<<endl;
}